2017-06-07 6 views
1

Ich bin Tring, um den Wert "ThisValueIwant" zu bekommen. Gibt es eine Möglichkeit, diesen Wert so einfach zu bekommen? Oder vielleicht eine andere Lösung gibt es für diese 2 ObservableCollectionLinq in ObservableCollection in ObservableCollection

public class Foo 
{ 
    public int number { get; set; } 
    public ObservableCollection<FooInFoo> Details { get; set; } 
} 

public class FooInFoo 
{ 
    public string thisValueIwant { get; set; } 
} 

public class TestClass 
{ 
    public void Test() 
    { 
     ObservableCollection<Foo> FooCollection = new ObservableCollection<Foo>(); 

     FooCollection.Add(new Foo{ 
      number =1, 
      Details = new ObservableCollection<FooInFoo>{ new FooInFoo {thisValueIwant = "very important string"}} 
     }); 

     string x = (from f in FooCollection 
        where f.number == 1 
        select ???) 
    } 
} 

Antwort

1

Seit ObservableCollection<FooInFoo> Details eine Sammlung ist, müssen Sie entscheiden, welche Daten Sie wollen: die erste, letzte, eine oder alle.

Angenommen, möchten Sie die erste:

var d = FooCollection.Where(f => f.Number == 1).FirstOrDefault()?.Details.FirstOrDefault()?.thisValueIwant; 

Oder das letzte:

var d = FooCollection.Where(f => f.Number == 1).FirstOrDefault()?.Details.LastOrDefault()?.thisValueIwant; 

oder alle (als Array materialisiert):

var ds = FooCollection.Where(f => f.Number == 1).FirstOrDefault()?.Details.Select(d => d.thisValueIwant).ToArray(); 
+0

Ihre Antwort ist logisch, aber ich habe einen Fehler, dass „Details“ ist kein Mitglied von „FooCollection“ Dieser funktioniert für mich jetzt: 'string x = (von f in FooCollection wo f.number == 1 wählen f.Details [0] .thisValueIwant) .FirstOrDefault();' Danke für Ihre Antwort – X89i

+0

Ja, tut mir leid. Verpasst das. Aktualisiert. –

1

Ein ObservableCollection<T> ist ein Collection<T> die implementiert IEnumerable<T>. Deshalb ist die Tatsache, dass Ihr FooCollection ist eine beobachtbare Sammlung nicht wichtig ist, können Sie es als eine Folge von Foo betrachten, ein IEnumerable<Foo> und ebenso ein IEnumerable<FooInFoo>

Ihr Code wird wie (sorry, ich weiß nur, wie in Methode schreiben Format) In kleinen Schritten:

IEnumerable<Foo> AllFooWithNumber1 = FooCollection 
    .Where(foo => foo.Number == 1); 

Wenn Sie sicher sind, gibt es genau eine weiter mit:

Foo fooWithNumber1 = AllFooWithNumber1.Single(); 

Betrachten 012 mitWenn Sie nicht sicher sind, dass es einen gibt.

Sobald Sie den Foo, die Sie möchten, können Sie die Details wählen:

IEnumerable<FooInFoo> detailsOfFooWithNumber1 = fooWithNumber1.Details; 
FooInFoo detailIWant = detailsOfFooWithNumber1 
    .Where(detail => some expression that uses detail...) 
    .SingleOrDefault(); 

string thisValueIWant = defailtIWant.thisValueIWant; 

Oder in einer Erklärung:

string thisValueIWant = FooCollection 
    .Where(foo => foo.Number == 1) 
    .Single() 
    .Details 
    .Where(detail => ...) 
    .Single() 
    .thisValueIWant; 

Probleme können auftreten, wenn Sie nicht sicher sind, gibt es eine Einzel Element.

Wenn Sie foo.Number für einen gegebenen Wert AND alle Details für einige Prädikat überprüfen möchten, verwenden Sie Enumerable.SelectMany. Dies wird immer dann verwendet, wenn Sie Folgen von Sequenzen haben (Arrays innerhalb von Arrays). Mit Select Sie all diese inneren Arrays aufzuzählen über, als ob es ein Array war:

IEnumerable<string> valuesIWant = FooCollection 
    .Where(foo => foo.Number == 1) 
    .SelectMany(foo => foo.Details) 
    // now you have one sequence of all FooInFoo that are Details within 
    // Foo objects with Number 1 
    .Where(detail => expression that selects the FooInFoo you want) 
    .Select(detail => detail.thisValueIWant); 
+0

Ich verstehe das "Where (detail =>)" in Ihrem Beispiel Code nicht. Ich erstelle es damit: 'string x = FooCollection.Where (foo => foo.number == 1) .Single(). Details.Single(). ThisValueIwant;' Und danke für die Antwort – X89i

+0

Wann immer Sie eine Linq-Funktion mit sehen eine Parameterdefinition wie Func , dann sollten Sie eine Funktion mit der Eingabe eines der Source-Elemente Ihrer Sequenz bereitstellen und einen TKey ausgeben. Sie tun dies mit Lambda: links von = = Sie setzen einen Parameternamen, der ein Element der Quellsequenz identifiziert.Auf der rechten Seite von => stellst du Code, der diesen Parameter als Eingabe hat und als Ausgabe einen TKey. Siehe auch https://www.codeproject.com/Tips/298963/Understand-Lambda-Expressions-in-minutes –