Свободное выражение и выражение запроса - есть ли какие-либо преимущества одного над другим?
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();
Есть ли разница между этими двумя или есть какое-то конкретное преимущество одного над другим?
14 ответов
Ни то, ни другое лучше: они служат различным потребностям. Синтаксис запроса вступает в свои права, когда вы хотите использовать несколько переменных диапазона. Это происходит в трех ситуациях:
- При использовании ключевого слова 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 to 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 };
Я предпочитаю использовать последний (иногда называемый "синтаксис понимания запроса"), когда я могу написать все выражение таким образом.
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();
Я считаю, что это немного легче читать.
У каждого стиля есть свои плюсы и минусы. Синтаксис запроса более приятен, когда речь идет о соединениях, и имеет полезное ключевое слово let, которое облегчает создание временных переменных внутри запроса.
Свободный синтаксис, с другой стороны, имеет гораздо больше методов и операций, которые не отображаются в синтаксисе запроса. Кроме того, поскольку они являются просто методами расширения, вы можете написать свой собственный.
Я обнаружил, что каждый раз, когда я начинаю писать оператор LINQ с использованием синтаксиса запроса, мне приходится помещать его в скобки и возвращаться к использованию беглых методов расширения LINQ. Синтаксис запроса просто не имеет достаточно функций для использования сам по себе.
В VB.NET я очень предпочитаю синтаксис запросов.
Я ненавижу повторять уродливое Function
-ключевое слово:
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#: /questions/40915652/razlichiya-v-sintaksise-linq-mezhdu-vbnet-i-c/40915662#40915662
Например, этот запрос 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);
Я вообще не понимаю синтаксис запроса. У меня просто нет причин для этого. let может быть достигнут с.Select и анонимными типами. Я просто думаю, что с "пунктуацией" все выглядит гораздо более организованно.
Свободный интерфейс, если есть только где. Если мне нужно выбрать или заказать, я обычно использую синтаксис запроса.
Свободный синтаксис действительно кажется более мощным, он также должен работать лучше для организации кода в небольшие многократно используемые методы.
Я знаю, что этот вопрос помечен C#, но синтаксис Fluent мучительно многословен с VB.NET.
Несмотря на то, что я понимаю и мне нравится свободный формат, я пока придерживался Query для удобства чтения. Люди, только знакомящиеся с LINQ, найдут Query намного удобнее для чтения.
Я предпочитаю синтаксис запроса, поскольку я пришел из традиционного веб-программирования с использованием SQL. Мне намного легче обернуть голову. Тем не менее, я думаю, что я начну использовать.Where(лямбда), поскольку он определенно намного короче.
Я использую Linq около 6 месяцев. Когда я впервые начал использовать его, я предпочел синтаксис запроса, так как он очень похож на T-SQL.
Но теперь я постепенно перехожу к первому, так как легко написать многократно используемые фрагменты кода в качестве методов расширения и просто связать их вместе. Хотя я считаю, что размещение каждого предложения в отдельной строке очень помогает с удобочитаемостью.
Мне очень нравится синтаксис Fluent, и я стараюсь использовать его там, где могу, но в некоторых случаях, например, когда я использую объединения, я обычно предпочитаю синтаксис запроса, в этих случаях мне легче читать, и я думаю, что некоторые люди Query (SQL-подобный) синтаксис более знаком, чем лямбды.
Из документов Microsoft:
Как правило, при написании запросов LINQ мы рекомендуем использовать синтаксис запроса, когда это возможно, и синтаксис метода, когда это необходимо . Между двумя разными формами нет семантической разницы или разницы в производительности. Выражения запроса часто более читабельны, чем эквивалентные выражения, написанные в синтаксисе метода.
Еще говорят:
Чтобы начать использовать LINQ, необязательно широко использовать лямбды. Однако некоторые запросы могут быть выражены только в синтаксисе метода, а некоторые из них требуют лямбда-выражений .
Я только что установил стандарты нашей компании, и мы применяем методы расширения. Я думаю, что это хорошая идея, чтобы выбрать один из других, а не смешивать их в коде. Методы расширения читаются больше как другой код.
Синтаксис понимания не имеет всех операторов и использует круглые скобки вокруг запроса и добавляет методы расширения, в конце концов, просто просит меня использовать методы расширения с самого начала.
Но по большей части это всего лишь личные предпочтения с несколькими исключениями.