Entity Framework 4 Single() vs First() vs FirstOrDefault()

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

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

Спасибо.

Ответ 1

Ниже представлен обзор различных методов:

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

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

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

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

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

Ответ 2

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

Ответ 3

Это действительно очень просто: Single возвращает один элемент и генерирует исключение, если нет ни одного, ни одного элемента. First возвращает первый элемент или бросает, когда нет элемента. FirstOrDefault вернет первый элемент или вернет значение по умолчанию (которое равно null, если данный тип является ссылочным типом), когда нет элемента.

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

Ответ 4

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

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

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

Ответ 5

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

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

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

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

Ответ 6

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

Single() или First() генерирует исключение, если результат не возвращается, SingleOrDefault() и FirstOrDefault ( ) ловит исключение и возвращает значение null или default (ResultDataType).