2009-10-22 12 views
7

Czy mogę uprościć to stwierdzenie wyrażeniem lambda?Wyrażenie Lambda

var project = from a in accounts 
       from ap in a.AccountProjects 
       where ap.AccountProjectID == accountProjectId 
       select ap; 

Odpowiedz

3

Szczerze mówiąc, wydaje mi się to całkiem jasne. Myślę, że lambda w tym przypadku może być mniej czytelna, tj. Coś podobnego do Brandona zamieszczonego poniżej.

(skradziony z postu Brandona)

var project = accounts.Select(a => a.AccountProjects) 
         .Where(x => x.AccountProjectID == accountProjectId); 

Jeśli chodzi o czytelność obawia się, myślę, że kilka pętli jest lepsze rozwiązanie lambda, i myślę, że rozwiązanie jest korzystne dla pętli.

+4

To zależy od tego, jak je napiszesz - dodaj przerwę linii przed ".Where" i nagle lambda jest rzeczywiście całkiem czytelna. –

+1

Zgadzam się z Edem. To, co teraz masz, jest doskonale czytelne, a lambda naprawdę niczego nie upraszcza. Byłoby to prawdopodobnie kwestią preferencji, jeśli cokolwiek. – Brandon

+1

Nawet z przerwą linii, dla mnie jest jeszcze mniej czytelna, ale myślę, że to rzecz subiektywna. Chyba chodzi o to; jest całkowicie jasne, przejdź do prawdziwego problemu! :) –

4
var project = accounts.SelectMany(a => a.AccountProjects) 
         .Where(x => x.AccountProjectID == accountProjectId); 

To, czy rzeczywiście jest prostsze, zależy od gustu.

+0

Myślę, że wiele z klauzul są koncepcyjnie prostsze niż niejawnie spłaszczone SelectMany, ale niezależnie od tego, nie jest cały punkt składni LINQ dać czystszą składnię niż te metody łańcuchowe? – Joren

+0

Te dwa podejścia są koncepcyjnie równoważne. Robią dokładnie to samo. Są to dwa różne sposoby wyrażania dokładnie tych samych zestawów operacji. Jak zauważyłem w mojej odpowiedzi, która jest "czystsza" lub "prostsza", jest kwestią gustu. – Mark

2

Zgadzam się z Edem Swangrenem. Wygląda to zwięźle i czytelnie.

Właściwie odpowiedź na to pytanie zależy od 3 czynników:

  1. Co chcesz osiągnąć - lepszej czytelności? lepsza wydajność? itp.
  2. Typ "kont"
  3. Sposób wykorzystania kolekcji wynikowej.

Jeśli chcesz uzyskać lepszą wydajność, a w przypadku "kont" jest listą, a wynikowa kolekcja będzie iterowana lub przekazywana do innej metody iteracji wkrótce po tych liniach kodu, zrobiłbym coś takiego :

List<Account> filteredAccounts = new List<Account>(); 
accounts.ForEach(a => { if (a.AccountProjectID == accountProjectId) filteredAccounts.Add(a); }); 

z pewnością jest to mniej czytelny wówczas oświadczenie LINQ, ale chciałbym wykorzystać te 2 linie zamiast accounts.Select .......

I na pewno jest dużo lepiej zoptymalizowany pod kątem wydajności, które zawsze uważam za ważne.

+2

Jakie są korzyści z wywołania 'ToList()' w zapytaniu LINQ? –

+0

Pytanie nie wymagało od ciebie optymalizacji, poprosiło Cię o jego uproszczenie. Zakładasz też całkiem duże założenie, gdy mówisz, że jest "znacznie lepiej zoptymalizowany pod kątem wydajności". Czy faktycznie to testowałeś? Czy masz dane, które potwierdzają twoje założenie? – Mark

+0

1. To, co nazywasz uproszczeniem - jest kwestią gustu. Myślę, że odpowiedziałem na to pytanie w poprzednim poście. 2. Oczywiście testowałem to. Inaczej nie chciałbym tego opublikować. Problem nie polega na wywołaniu ToList w zapytaniu. Średnio LINQ dla obiektów jest ponad dwa razy wolniejszy niż tradycyjne techniki (na przykład iteracja przy użyciu cyklu foreach). Nie wierz mi? Możesz z łatwością przeprowadzić mikroprzedsiębiorstwo po prostu google out. Zastosowana tutaj metoda rozszerzenia ForEach wraz z wyrażeniem lambda zapewnia jeszcze lepszą wydajność niż cykl foreach. Dokładam wszelkich starań, aby dowiedzieć się, jakie rzeczy kosztują, uwierz mi, – Alexander

0
accounts 
    .SelectMany (
     a => AccountProjects, 
     (a, ct) => 
     new 
     { 
      a = a, 
      ap = ap 
     } 
    ) 
    .Where (t => (t.ap.AccountProjectID == t.a.accountProjectId)) 
    .Select (t => t.ap) 
Powiązane problemy