Вільне вираження та вираження запитів - Чи є якась вигода від одного над іншим?


255

LINQ - це одне з найбільших удосконалень .NET з часу дженерики, і це економить мені тони часу та рядки коду. Однак вільний синтаксис здається мені набагато більш природним, ніж синтаксис виразу запиту.

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();

Чи є якась різниця між двома або є якась вигода однієї над іншими?


1
Для складних запитів я вважаю, що синтаксис лямбда є більш зрозумілим / читабельним, але синтаксис запитів просто просто гарніший.
nawfal

Відповіді:


255

Ні кращого: вони обслуговують різні потреби. Синтаксис запитів набуває власних зусиль, коли потрібно використовувати декілька змінних діапазонів . Це відбувається в трьох ситуаціях:

  • При використанні ключового слова let
  • Коли у вас є кілька генераторів ( із пунктів)
  • Коли робиш приєднання

Ось приклад (із зразків 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;

Тепер порівняйте це з тим же, що в синтаксисі методу:

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);

Синтаксис методу, з іншого боку, розкриває повну гаму операторів запитів і більш стислий з простими запитами. Ви можете отримати найкраще з обох світів, змішавши запит і синтаксис методу. Це часто робиться в LINQ для 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 };

2
Гарна відповідь. Чи можете ви розповісти трохи більше про те, що робить ".Select (name => new {name, fName})"?
quillbreaker

12
Він вибирає окреме слово (Анна, Вілліямс, Джон та ін.) Разом із повним ім'ям в анонімному типі. Це дозволяє "носити" оригінальне повне ім'я, щоб ви мали доступ до повного імені та окремого слова в решті запиту.
Джо Альбахарі

58

Я вважаю за краще використовувати останній (іноді його називають «синтаксисом розуміння запитів»), коли я можу таким чином записати весь вираз.

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

var title = titlesQuery.FirstOrDefault();

Як тільки я повинен додати (дужки) і .MethodCalls(), я змінюю.

Коли я використовую попередній, я зазвичай кладу по одному пункту на рядок, наприклад:

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

Я вважаю, що трохи легше читати.


29

У кожного стилю є свої плюси і мінуси. Синтаксис запитів приємніший, коли мова йде про приєднання, і він має корисне ключове слово хай, що робить створення тимчасових змінних всередині запиту простим.

З іншого боку, вільний синтаксис має набагато більше методів та операцій, які не піддаються впливу синтаксису запитів. Крім того, оскільки це лише методи розширення, ви можете написати свій власний.

Я виявив, що кожного разу, коли я починаю писати оператор LINQ, використовуючи синтаксис запитів, мені в кінцевому підсумку потрібно вставити його в круглі дужки і повернутися до використання методів розширення LINQ. Синтаксис запиту просто не має достатньо функцій, які він може використовувати сам.


"оскільки це лише методи розширення, ви можете написати свій власний." - Ви б зіткнулися з цією проблемою? stackoverflow.com/a/3850254/1175496
Червоний горох

20

У VB.NET я дуже віддаю перевагу синтаксису запитів.

Я ненавиджу повторювати некрасиве Function-keyword:

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)

Цей акуратний запит, на мою думку, набагато легше читати і підтримувати:

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

Синтаксис запитів VB.NET також є більш потужним та менш дослідним, ніж у C #: https://stackoverflow.com/a/6515130/284240

Наприклад, це запит LINQ до DataSet (Objects)

VB.NET:

Dim first10Rows = From r In dataTable1 Take 10

C #:

var first10Rows = (from r in dataTable1.AsEnumerable() 
                   select r)
                   .Take(10);

9
Мої симпатії тим розробникам VB, які не можуть використовувати стиль запиту.
nawfal

1
Ваш останній приклад C # занадто спрощений, щоб бути цінним: ви просто напишете `dataTable1.AsEnumerable (). Take (10);
Емір

@Emyr: мій останній абзац, який починається з "Синтаксис запитів VB.NET, також є більш потужним і менш дослівним, ніж у C #", просто порівнюючи синтаксис запитів VB.NET з C #, ви використовуєте синтаксис методу.
Тім Шмелтер

15

Я взагалі не отримую синтаксис запитів. В моїй думці це просто немає причин. нехай можна отримати з .Select та анонімні типи. Я просто думаю, що речі виглядають набагато організованішими з "пунктуацією".


9
Кілька приєднань можуть отримати досить трудомісткий досить швидкий синтаксис. Я, як правило, самостійно використовую вільно - якщо не приєднується приєднання.
Роман Старков

1
@Instance Hunter: Те саме тут. Мені знадобилося досить багато часу, щоб почати розуміти ідею вільного синтаксису. У поєднанні з потужною чисельністю та ідеєю "чистих" функцій, мені зараз дуже подобається, і раніше хитрі ситуації, які не мали приємного представлення коду. Для ye-ole-SQL-частини мозку все-таки є благословенням синтаксису запитів.
Ксан-Кун Кларк-Девіс,

13

Вільний інтерфейс, якщо є лише де. Якщо мені потрібно виділити або замовити, я зазвичай використовую синтаксис Query.


8

Вільний синтаксис справді здається більш потужним, він також повинен працювати краще для організації коду в невеликі багаторазові методи.


5

Я знаю, що це питання позначене C #, але синтаксис Fluent є болісно багатослівним з VB.NET.


4

Мені дуже подобається синтаксис Fluent, і я намагаюся використовувати його там, де можу, але в певних випадках, наприклад, коли я використовую приєднання, я зазвичай віддаю перевагу синтаксису Запиту, в тих випадках мені стає легше читати, і я думаю, що деякі люди є більш звичним синтаксису Query (SQL-подібний), ніж лямбда.


4

Хоча я розумію і люблю вільний формат, я поки що затримався на запиті з міркувань читабельності. Люди, які тільки знайомляться з LINQ, знайдуть Запит набагато зручнішим для читання.


4

Я віддаю перевагу синтаксису запитів, оскільки я прийшов із традиційного веб-програмування за допомогою SQL. Мені набагато простіше обернути голову. Однак, я думаю, я почну використовувати .Where (лямбда), оскільки це, безумовно, набагато коротше.


4

Я використовую Linq вже близько 6 місяців. Коли я вперше почав його використовувати, я віддав перевагу синтаксису запитів, оскільки він дуже схожий на T-SQL.

Але я поступово зараз переходжу до колишнього, так як легко написати шматки багаторазового використання коду як методи розширення та просто зв'язати їх між собою. Хоча я вважаю, що розміщення кожного пункту у власному рядку дуже допомагає при читанні.


3

Я щойно встановив стандарти нашої компанії і ми застосовуємо методи розширення. Я думаю, що це гарна ідея вибрати один за іншим і не змішувати їх у коді. Методи розширення читають більше, як і інший код.

Синтаксис розуміння не у всіх операторів, які використовують круглі дужки навколо запиту, і додають методи розширення, зрештою, просто просять мене використовувати методи розширення з самого початку.

Але здебільшого це лише особисті переваги за кількома винятками.


3
Я не буду виконувати особисті переваги .. Але це я.
Memet Olsen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.