LINQ: Точечная запись или выражение запроса
Я начинаю использовать LINQ вообще (пока toXML и toSQL). Я видел, что иногда есть два или более способов достичь одинаковых результатов. Возьмите этот простой пример, насколько я понимаю, оба возвращают одно и то же:
SomeDataContext dc = new SomeDataContext();
var queue = from q in dc.SomeTable
where q.SomeDate <= DateTime.Now && q.Locked != true
orderby (q.Priority, q.TimeCreated)
select q;
var queue2 = dc.SomeTable
.Where( q => q.SomeDate <= DateTime.Now && q.Locked != true )
.OrderBy(q => q.Priority)
.ThenBy(q => q.TimeCreated);
Идея состоит в том, что есть два способа выразить одно и то же; Я понимаю, что у первого метода есть некоторые ограничения и что "точечная нотация" более полная, но кроме этого, есть ли другие преимущества?
Ответы
Ответ 1
Обозначение "точка" обычно называется синтаксисом лямбда. Первая нотация относится к числу имен, но я обычно называю это синтаксисом запроса.
Я работаю над командой из 10 разработчиков, и мы подробно рассуждаем о том, что мы должны использовать в качестве стандарта. В целом, более опытные разработчики (LINQ) мигрируют в сторону синтаксиса лямбда, но есть значительные исключения.
Лямбда более лаконична, но выполнение нескольких столовых объединений - это кошмар. Соединения просто намного чище с синтаксисом запроса. Оборотная сторона заключается в том, что существует ряд операций LINQ, которые существуют только в синтаксисе Lambda: Single(), First(), Count() и т.д.
Итак, используйте то, с чем вы чувствуете себя наиболее комфортно, и понимаете, что по мере приобретения опыта ваши предпочтения, скорее всего, изменятся. Существует большая ценность в том, чтобы читать и то и другое, и, безусловно, будут ситуации, когда вы должны использовать немного их обоих. Другие ситуации предоставят им один стиль другому. В конце концов, все это переводится в один и тот же исполняемый код.
Ответ 2
Я использую любой синтаксис, более читаемый для моего запроса, в каждом конкретном случае.
По возможности, я стараюсь избегать смешивания и сопоставления двух, хотя иногда это нормально (если это один вызов First()
в конце запроса, например). Отсроченное выполнение означает, что он также эффективен для использования выражения запроса и присваивает результат переменной, а затем использует точечную нотацию с использованием этой переменной:
var query = from x in y
orderby z
group x by x.Name into groups
// etc
select foo;
var page = query.Skip(50).Take(10);
Как говорили другие, выражения запроса просто переводятся в "нормальный" С# 3 без выражений запроса, поэтому для этого не начисляется штраф.
Ответ 3
Ну, нота "точка" может быть намного короче. Возьмем:
var result = from p in dc.Products
where p.Id > 5
select p;
или
var result = dc.Products.Where(p => p.Id > 5);
Я предпочитаю последний, поскольку он намного короче и читаем.
Ответ 4
Я нахожу Лямбда-нотацию более аккуратной и более лаконичной. Я просто нахожу, что это раздражает, что если в вызове метода есть выражение Lambda где угодно, вы не можете изменять код на лету в режиме отладки...
Ответ 5
Они компилируются в один и тот же код, или, скорее, сначала сначала переводятся на второй, а затем скомпилированы.
Вы правы, что разница в том, что первая версия чище, но более ограничена. Во втором вы можете, например, использовать уже существующих делегатов, например:
Func<int, bool> isEven = i => i%2 == 0;
Enumerable.Range(10).Where(isEven).ToList().ForEach(Console.WriteLine);