Płynność i ekspresja zapytań-czy jest jakaś korzyść(y) jednego nad drugim?

LINQ jest jednym z największych ulepszeń do. NET od czasów generics i oszczędza mi mnóstwo czasu i linii kodu. Jednak składnia płynna wydaje mi się dużo bardziej naturalna niż składnia wyrażenia zapytania.

var title = entries.Where(e => e.Approved)
    .OrderBy(e => e.Rating).Select(e => e.Title)
    .FirstOrDefault();

var query = (from e in entries
             where e.Approved
             orderby e.Rating
             select e.Title).FirstOrDefault();

Czy jest jakaś różnica między tymi dwoma, czy jest jakaś szczególna korzyść z jednego nad drugim?

 238
Author: Uwe Keim, 2008-10-18

13 answers

Ani nie jest lepiej: służą innym potrzebom. Składnia zapytań pojawia się sama, gdy chcesz wykorzystać wiele zmiennych zakresu. Dzieje się tak w trzech sytuacjach:

  • przy użyciu słowa kluczowego let
  • Gdy masz wiele generatorów (z})
  • podczas wykonywania połączeń

Oto przykład (z sampli LINQPad):

string[] fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };

var query =
  from fullName in fullNames
  from name in fullName.Split()
  orderby fullName, name
  select name + " came from " + fullName;

Teraz porównaj to do tego samego w składni metody:

var query = fullNames
  .SelectMany (fName => fName.Split().Select (name => new { name, fName } ))
  .OrderBy (x => x.fName)
  .ThenBy  (x => x.name)
  .Select  (x => x.name + " came from " + x.fName);

Składnia metody, na z drugiej strony, ujawnia pełną gamę operatorów zapytań i jest bardziej zwięzła dzięki prostym zapytaniom. Możesz uzyskać to, co najlepsze z obu światów, mieszając składnię zapytań i metod. Jest to często wykonywane w zapytaniach LINQ do SQL:

var query =
  from c in db.Customers
  let totalSpend = c.Purchases.Sum (p => p.Price)    // Method syntax here
  where totalSpend > 1000
  from p in c.Purchases
  select new { p.Description, totalSpend, c.Address.State };
 236
Author: Joe Albahari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-05 03:20:12

Wolę używać tego drugiego (czasami nazywanego "składnią rozumienia zapytań"), Gdy mogę w ten sposób napisać całe wyrażenie.

var titlesQuery = from e in entries
                  where e.Approved
                  orderby e.Rating
                  select e.Titles;

var title = titlesQuery.FirstOrDefault();

Jak tylko muszę dodać (nawiasy) i .MethodCalls(), zmieniam.

Kiedy używam pierwszego, Zwykle umieszczam jedną klauzulę w linii, tak:

var title = entries
    .Where (e => e.Approved)
    .OrderBy (e => e.Rating)
    .Select (e => e.Title)
    .FirstOrDefault();
Wydaje mi się, że to trochę łatwiejsze do odczytania.
 58
Author: Jay Bazuzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-26 17:14:23

Każdy styl ma swoje plusy i minusy. Składnia zapytań jest ładniejsza, jeśli chodzi o złączenia i ma użyteczne słowo kluczowe let , które ułatwia tworzenie tymczasowych zmiennych wewnątrz zapytania.

Składnia Płynna z drugiej strony ma znacznie więcej metod i operacji, które nie są ujawniane przez składnię zapytania. Również ponieważ są to tylko metody rozszerzenia, możesz napisać własne.

Odkryłem, że za każdym razem, gdy zaczynam pisać instrukcję LINQ używając składni zapytania kończę na aby umieścić go w nawiasie i wrócić do używania płynnych metod rozszerzenia LINQ. Składnia zapytań po prostu nie ma wystarczającej liczby funkcji do użycia sama.

 29
Author: James Newton-King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-13 21:57:19

W VB.NET bardzo wolę składnię zapytań.

Nienawidzę powtarzać brzydkiego Function-słowo kluczowe:

Dim fullNames = { "Anne Williams", "John Fred Smith", "Sue Green" };
Dim query =
     fullNames.SelectMany(Function(fName) fName.Split().
     Select(Function(Name) New With {Name, fName})).
     OrderBy(Function(x) x.fName).
     ThenBy(Function(x) x.Name).
     Select(Function(x) x.Name & " came from " & x.fName)

To porządne zapytanie jest moim zdaniem o wiele bardziej czytelne i możliwe do utrzymania:

query = From fullName In fullNames
        From name In fullName.Split()
        Order By fullName, name
        Select name & " came from " & fullName

VB.NET składnia zapytań jest również potężniejsza i mniej wyrazista niż w C#: https://stackoverflow.com/a/6515130/284240

Na przykład zapytanie LINQ to DataSet (Objects)

VB.NET:

Dim first10Rows = From r In dataTable1 Take 10

C#:

var first10Rows = (from r in dataTable1.AsEnumerable() 
                   select r)
                   .Take(10);
 20
Author: Tim Schmelter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:50

W ogóle nie rozumiem składni zapytania. Po prostu nie mam powodu. niech może być achieved z .Typy Select i anonimowe. Wydaje mi się, że sprawy wyglądają lepiej z tą "interpunkcją".

 14
Author: Instance Hunter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-28 06:01:32

Płynny interfejs, jeśli jest tylko gdzie. Jeśli potrzebuję select lub orderby, zazwyczaj używam składni zapytania.

 13
Author: James Curran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-18 03:52:46

Płynna składnia wydaje się rzeczywiście potężniejsza, powinna również działać lepiej przy organizowaniu kodu w małe metody wielokrotnego użytku.

 8
Author: Kozyarchuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-18 03:42:24

Wiem, że to pytanie jest oznaczone C#, ale płynna składnia jest boleśnie VB.NET.

 5
Author: Larsenal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-11 19:45:26

Bardzo lubię składnię Fluent i staram się jej używać tam, gdzie mogę, ale w niektórych przypadkach, na przykład tam, gdzie używam joins, Zwykle preferuję składnię Query, w tych przypadkach łatwiej mi ją czytać i myślę, że niektórzy ludzie są bardziej zaznajomieni ze składnią Query (podobną do SQL) niż lambda.

 4
Author: CMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-18 03:53:50

Chociaż Rozumiem i lubię płynny format, utknąłem w Pytaniu na razie ze względu na czytelność. Osoby dopiero co zapoznane z LINQ znajdą Zapytanie o wiele wygodniejsze do czytania.

 4
Author: LizB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-18 04:19:43

Wolę składnię zapytań, ponieważ pochodzę z tradycyjnego programowania stron internetowych przy użyciu SQL. O wiele łatwiej jest mi się ogarnąć. Jednak myślę, że zacznę wykorzystywać .Gdzie (lambda), ponieważ jest zdecydowanie znacznie krótszy.

 4
Author: Steve Tranby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-19 05:21:06

Używam Linq już od około 6 miesięcy. Kiedy po raz pierwszy zacząłem go używać, wolałem składnię zapytania, ponieważ jest bardzo podobna do T-SQL.

Ale, stopniowo przejdę teraz do tego pierwszego, ponieważ łatwo jest napisać fragmenty kodu wielokrotnego użytku jako metody rozszerzeń i po prostu połączyć je ze sobą. Chociaż uważam, że umieszczenie każdej klauzuli na własnej linii bardzo pomaga w czytelności.

 4
Author: Antony Scott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-14 10:23:56

Właśnie ustaliłem standardy naszej firmy i wymuszamy stosowanie metod rozszerzenia. Myślę, że to dobry pomysł, aby wybrać jeden nad drugim i nie mieszać ich w kodzie. Metody rozszerzeń są podobne do innych kodów.

Składnia rozumienia nie ma wszystkich operatorów i używanie nawiasów wokół zapytania i dodawania metod rozszerzeń po prostu prosi mnie o używanie metod rozszerzeń od samego początku.

Ale w przeważającej części jest to tylko osobiste preferencje z kilka wyjątków.

 3
Author: Rodi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-01 07:25:13