2016-08-14 2 views
0

Ich habe eine Antwort von einer SOAP-Abfrage zurückgegeben, die nach dieser Bild hierarchische Daten mit jeder Zeile/Feld als Name/Wert-Objekte in einem Array hat: object hierarchyselect-Anweisung für LINQ in Select

Ich zeige die erstes Feld 'sequennumb', aber es gibt viele Felder im Fields-Array.

Jetzt kann ich durch jedes dieser Fields-Array-Elemente iterieren, eine massive switch/case-Anweisung ausführen und das Objekt in etwas "flatten", das ich brauche. Aber ich fragte mich, ob es einen besseren Weg mit Linq gab.

Was ich haben will, ist so etwas wie diese:

while (response.Records != null) 
{ 
    var rows = from row in response.Records 
        from field in row.Fields 
        where field.Name == "status" && field.Value[0] != 'X' 
        select new { 
         seqnumb = from f in field where f.Name == "seqnumb" select f.Value 
        }; 
    foreach (var row in rows) 
    { 

    } 
    // get new response.. 
} 

Wenn ein Objekt mit dem Wert seqnumb = 3 (und vielen anderen Parametern von Array Fields) zurückgeführt wird.

Zur Zeit habe ich 'Zeile auswählen' als die letzte Anweisung in der Linq-Anweisung, die ich mit einem Schalter/Fall durchlaufen, die funktioniert, aber hat viel Code, und ich möchte mein Linq Verständnis zu verbessern.

danke fürs lesen.

+0

So tun Sie mit Logik in den leeren Block in Ihrem Beispiel füllen wollen ein Objekt des Typs T für jede "Zeile" in "response.Records" zu erstellen, oder möchten Sie Ihre Deklaration von "Zeilen" durch einen Linq-Ausdruck ersetzen, der ein Iterable of Object vom Typ T erzeugt? So oder so, Sie müssen einen Konstruktor oder eine Fabrik für T verwenden. – Peter

+0

Ich fragte mich, wie es in Linq wenn möglich alles zu tun. Derzeit mache ich eine foreach (Zeile in Zeilen) {foreach (Feld in Zeile.Felder) {}} Typ Iteration. – pgee70

Antwort

0

Sie wissen nicht, ob ich Ihre Beschreibung oder nicht vollständig bin ergreifend, aber es klingt wie das für mich funktionieren würde:

var fields = 
from row in response.Records 
where 
    row.Fields.Any(f1 => f1.Name == "status" && f1.Value != 'X') && 
    row.Fields.Any(f2 => f2.Name == "seqnumb" && f2.Value == "3") 
select(r => r.Fields); 

/* 
* fields, if not null, now contains the complete fields collection 
* of the row that you appear to be interested in. 
* 
* You mentioned wanting a row that has a field named seqnumb == "3" 
* and your code also showed that you want to ensure that the fields 
* collection for that row have a field named "status" != 'X' 
* 
* You can pull--from var fields above--a list of only 
* the fields that you are interested in via something like the below 
*/ 

List<string> fieldNamesWanted = new List<string> 
    {"seqnumb", "someotherfield", "anotherfield"}; 

var onlyTheFieldsYouWant = 
(
    from field in fields 
    where fieldNamesWanted.Any(x => x == field.Name) 
    select field 
).ToList();