LINQ: точечная нотация против выражения запроса - PullRequest
55 голосов
/ 10 марта 2009

Я начинаю использовать 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);

Помимо любой ошибки, которую я мог допустить в синтаксисе или в пропущенном параметре или разнице, идея состоит в том, что есть два способа выразить одно и то же; Я понимаю, что у первого метода есть некоторые ограничения и что «точечная нотация» является более полной, но кроме этого есть ли другие преимущества?

Ответы [ 5 ]

51 голосов
/ 10 марта 2009

«Точечная» запись обычно называется лямбда-синтаксисом. Первая нотация состоит из нескольких имен, но я обычно называю это синтаксисом запроса.

Я работаю в команде из 10 разработчиков, и мы долго спорим о том, что нам следует использовать в качестве стандарта. В целом, более опытные (с LINQ) разработчики переходят на синтаксис Lambda, но есть существенные исключения.

Лямбда более лаконична, но выполнение объединения нескольких таблиц - это кошмар. Объединения намного понятнее с синтаксисом запроса. С другой стороны, существует ряд операций LINQ, которые существуют только в синтаксисе Lambda: Single (), First (), Count () и т. Д.

Итак, используйте то, что вам наиболее удобно, и осознайте, что по мере накопления опыта ваши предпочтения, скорее всего, изменятся. Очень важно иметь возможность читать оба, и, безусловно, будут ситуации, когда вам придется использовать немного того и другого. Другие ситуации предоставят себя одному стилю над другим. В конце концов все это переводится в один и тот же исполняемый код.

28 голосов
/ 10 марта 2009

Я использую тот синтаксис, который более читаем для моего запроса, в каждом конкретном случае.

Где это возможно, я стараюсь избегать смешивания и сопоставления двух, хотя иногда это нормально (например, если это единственный вызов 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);

Как уже говорили другие, выражения запросов просто переводятся в "обычный" C # 3 без выражений запросов, поэтому за это не нужно платить.

8 голосов
/ 10 марта 2009

Ну, точечная запись может быть намного короче. Возьмите:

var result = from p in dc.Products
             where p.Id > 5
             select p;

или

var result = dc.Products.Where(p => p.Id > 5);

Я предпочитаю последнее, поскольку оно намного короче и более читаемо.

3 голосов
/ 19 августа 2009

Я считаю лямбда-нотацию аккуратнее и лаконичнее. Я просто нахожу это раздражающим, что если у вас есть лямбда-выражение в любом месте внутри вызова метода, вы не можете изменять код на лету в режиме отладки ...

2 голосов
/ 10 марта 2009

Они компилируются в один и тот же код, точнее, сначала первый переводится во второй, а затем компилируется.

Вы правы, разница в том, что первая версия чище, но более ограничена. Во втором вы можете, например, использовать уже существующие делегаты, например:

Func<int, bool> isEven = i => i%2 == 0;
Enumerable.Range(10).Where(isEven).ToList().ForEach(Console.WriteLine);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...