Entity Framework 4 Single () против First () против FirstOrDefault () - PullRequest
107 голосов
/ 15 августа 2010

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

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

Спасибо.

Ответы [ 6 ]

190 голосов
/ 15 августа 2010

Вот обзор различных методов:

  • Find () - когда вы хотите получить предмет по первичному ключу. Это вернет ноль, если не может найти элемент. Он будет смотреться в контексте перед переходом к базе данных (как отметил Ярон в комментариях), что может быть важным фактором эффективности, если вам нужно получить один и тот же объект несколько раз, пока один и тот же контекст активен.

  • Single () - когда вы ожидаете, что по запросу будет возвращен ровно один элемент. Это вызовет исключение, если запрос не возвращает ровно один элемент.

  • SingleOrDefault () - когда вы ожидаете, что по запросу будет возвращено ноль или один элемент (т.е. вы не уверены, существует ли элемент с данным ключом). Это вызовет исключение, если запрос не возвращает ноль или один элемент.

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

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

19 голосов
/ 16 августа 2010

Я всегда склонен использовать FirstOrDefault. Если вы действительно хотите быть придирчивыми к производительности, вам следует использовать FirstOrDefault в EF. Под прикрытием SingleOrDefault использует top (2) в запросе, потому что он должен проверить, есть ли вторая строка, которая соответствует критериям, и, если это так, выдает исключение. В основном в SingleOrDefault вы говорите, что хотите создать исключение, если ваш запрос возвращает более 1 записи.

15 голосов
/ 15 августа 2010

Это действительно очень просто: Single возвращает один элемент и выдает исключение, если нет ни одного, или более одного элемента.First вернет первый предмет или бросок, когда предмета нет.FirstOrDefault вернет первый элемент или вернет значение по умолчанию (которое равно null в случае, если данный тип является ссылочным типом), когда элемента нет.иметь.Однако обратите внимание, что базовая реализация может иметь другое поведение.Хотя Entity Framework подчиняется этому, O / RM, такой как LLBLGen, также может возвращать null при вызове First, что является очень странной вещью.Это было очень странное (и упрямое) решение дизайнера IMO.

8 голосов
/ 15 августа 2010

Каждый из четырех методов имеет свое место;Хотя на самом деле у вас есть только две разные операции.

  • Первый - ожидание набора результатов, который содержит несколько элементов, дайте мне первый элемент в этом наборе.
  • Один - ожидание одного результатаверните мне этот элемент.

В версии xxxxOrDefault () просто добавлено: «Я не хочу рассматривать пустой набор результатов как исключительное обстоятельство».

3 голосов
/ 04 декабря 2015

С другой стороны, вы можете разделить эти методы на основную логику, например:

  • Метод будет запрашивать базу данных напрямую : Single (), SingleOrDefault(), First (), FirstOrDefault ()
  • Метод выполнит поиск в кэше, прежде чем даже выполнить запрос к базе данных : Find ()

Некоторые подробности производительности, особенно во втором случае, вы можете посмотреть здесь: https://msdn.microsoft.com/en-us/data/hh949853.aspx?f=255&MSPPError=-2147217396#3

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

0 голосов
/ 26 июля 2013

Single () и SingleOrDefault () обычно используется для уникальных идентификаторов, таких как идентификаторы, тогда как First () или FirstOrDefault () обычно используется для запроса, который может иметь несколько результатов, но вы хотите только "Top 1" .

Single () или First () вызовет исключение, если результат не будет возвращен, SingleOrDefault () и FirstOrDefault () перехватывает исключение и возвращает ноль или значение по умолчанию (ResultDataType).

...