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).