LINQ, единственный по сравнению со сначала

LINQ:

Действительно ли более эффективно использовать Single() оператор First() когда когда-нибудь я буду знать наверняка, что запрос возвратит единственную запись?

Существует ли различие?

202
задан Developer 5 April 2013 в 06:24
поделиться

7 ответов

Если вы ожидаете одиночной записи, всегда полезно указать ее явно в коде.

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

Примечание. В моем коде я обычно использую FirstOrDefault () и SingleOrDefault () , но это другой вопрос.

Возьмем, к примеру, таблицу, в которой хранятся клиентов на разных языках с использованием составного ключа ( ID , Lang ):

DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).First();

Этот код выше вводит возможную логическую ошибку (трудно отследить). Он вернет более одной записи (при условии, что у вас есть запись о клиенте на нескольких языках), но он всегда будет возвращать только первую ... что иногда может работать ... но не другие. Это непредсказуемо.

Поскольку ваше намерение состоит в том, чтобы вернуть Single Customer , используйте Single () ;

Следующее вызовет исключение (что вы и хотите в данном случае):

DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).Single();

​​Затем вы просто бьете себя по лбу и говорите себе ... УПС! Я забыл языковое поле! Ниже приводится правильная версия:

DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 && c.Lang == "en" ).Single();

First () полезна в следующем сценарии:

DBContext db = new DBContext();
NewsItem newsitem = db.NewsItems.OrderByDescending( n => n.AddedDate ).First();

Он вернет ОДИН объект, и, поскольку вы используете сортировку, это будет самая последняя возвращенная запись.

Использование Single () , когда вы чувствуете, что он должен явно всегда возвращать 1 запись, поможет вам избежать логических ошибок.

300
ответ дан 23 November 2019 в 04:59
поделиться

Многие люди, которых я знаю, используют FirstOrDefault (), но я предпочитаю использовать SingleOrDefault () чаще, потому что, если бы их было больше, часто возникала бы некоторая несогласованность данных. Однако это имеет дело с LINQ-to-Objects.

3
ответ дан 23 November 2019 в 04:59
поделиться

Если я помню, Single () проверяет, есть ли еще один элемент после первого (и выдает исключение, если это так), а First () прекращается после получения. Оба генерируют исключение, если последовательность пуста.

Лично я всегда использую First ().

14
ответ дан 23 November 2019 в 04:59
поделиться

Если вы не хотите, чтобы исключение создавалось специально в случае наличия более одного элемента , используйте First () .

Оба эффективны, возьмем первый пункт. First () немного более эффективен, потому что он не утруждает себя проверкой наличия второго элемента.

Единственное отличие состоит в том, что Single () ожидает, что в начале перечисления будет только один элемент, и вызовет исключение, если их больше одного. Вы используете .Single () , если хотите, чтобы в этом случае было создано исключение .

16
ответ дан 23 November 2019 в 04:59
поделиться

Single вызовет исключение, если найдет несколько записей, соответствующих критериям. Сначала всегда будет выбираться первая запись из списка. Если запрос возвращает только 1 запись, вы можете использовать First () .

Оба вызовут исключение InvalidOperationException , если коллекция пуста. В качестве альтернативы вы можете использовать SingleOrDefault () . Это не вызовет исключения, если список пуст

67
ответ дан 23 November 2019 в 04:59
поделиться

Между этими двумя методами есть тонкая семантическая разница.

Используйте Single для извлечения первого (и единственного) элемента из последовательности, которая должна содержать один элемент и не более. Если последовательность содержит более одного элемента, ваш вызов Single вызовет выдачу исключения, поскольку вы указали, что должен быть только один элемент.

Используйте Сначала , чтобы извлечь первый элемент из последовательности, которая может содержать любое количество элементов. Если в последовательности больше одного элемента, ваш вызов First не вызовет выброса исключения, поскольку вы указали, что вам нужен только первый элемент в последовательности, и не заботитесь о том, существуют ли другие элементы.

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

18
ответ дан 23 November 2019 в 04:59
поделиться

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

5
ответ дан 23 November 2019 в 04:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: