Когда использовать .First и когда использовать .FirstOrDefault с LINQ? - PullRequest
768 голосов
/ 21 июня 2009

Я искал и не нашел четкого ответа относительно того, когда вы хотите использовать .First и когда вы хотите использовать .FirstOrDefault с LINQ.

  • Когда вы хотите использовать .First? Только когда вы хотите перехватить исключение, если результаты не возвращены?

    var result = List.Where(x => x == "foo").First();
    
  • А когда вы захотите использовать .FirstOrDefault? Когда вам всегда нужен тип по умолчанию, если нет результата?

    var result = List.Where(x => x == "foo").FirstOrDefault();
    
  • И в этом отношении, как насчет Take?

    var result = List.Where(x => x == "foo").Take(1);
    

Ответы [ 13 ]

758 голосов
/ 21 июня 2009

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

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

Наконец, разница между First() и Take(1) в том, что First() возвращает сам элемент, а Take(1) возвращает последовательность элементов, которая содержит ровно один элемент.

259 голосов
/ 21 июня 2009

.First вызовет исключение, если нет результатов. .FirstOrDefault не будет, он просто вернет либо ноль (ссылочные типы), либо значение по умолчанию для типа значения (например, как 0 для int.) Вопрос здесь не в том, когда вам нужен тип по умолчанию, а в следующем: готовы ли вы обрабатывать исключение или обрабатывать значение по умолчанию? Поскольку исключения должны быть исключительными, FirstOrDefault предпочтительнее, когда вы не уверены, что собираетесь получить результаты из своего запроса. Когда логически данные должны быть там, обработка исключений может быть рассмотрена.

Skip() и Take() обычно используются при настройке подкачки в результатах. (Например, показ первых 10 результатов и следующих 10 на следующей странице и т. Д.)

Надеюсь, это поможет.

106 голосов
/ 21 июня 2009

.First () сгенерирует исключение, если нет возвращаемой строки, а .FirstOrDefault () вернет значение по умолчанию (NULL для всех ссылочных типов).

Так что, если вы готовы и готовы обработать возможное исключение, .First() хорошо. Если вы все равно предпочитаете проверять возвращаемое значение для! = Null, то .FirstOrDefault() - ваш лучший выбор.

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

61 голосов
/ 02 сентября 2014

Первый ()

  1. Возвращает первый элемент последовательности.
  2. Выдает ошибку, когда в результате отсутствует элемент или источник равен нулю.
  3. Вы должны использовать его, если ожидается более одного элемента и вам нужен только первый элемент.

FirstOrDefault ()

  1. Возвращает первый элемент последовательности или значение по умолчанию, если элемент не найден.
  2. Выдает ошибку, только если источник нулевой.
  3. Вы должны использовать его, если ожидается более одного элемента, и вы хотите только первый элемент. Также хорошо, если результат пуст.

У нас есть таблица UserInfos, в которой есть несколько записей, как показано ниже. На основе этой таблицы ниже я создал пример ...

UserInfo Table

Как использовать First ()

var result = dc.UserInfos.First(x => x.ID == 1);

Существует только одна запись, где ID == 1. Должен вернуть эту запись
ID: 1 Имя: Маниш Фамилия: Дубей Электронная почта: xyz@xyz.com

var result = dc.UserInfos.First(x => x.FName == "Rahul");   

Есть несколько записей, где FName == "Rahul". Первая запись должна быть возвращена.
ID: 7 Имя: Рахул Фамилия: Шарма Электронная почта: xyz1@xyz.com

var result = dc.UserInfos.First(x => x.ID ==13);

Нет записи с идентификатором == 13. Должна возникнуть ошибка.
InvalidOperationException: последовательность не содержит элементов

Как использовать FirstOrDefault ()

var result = dc.UserInfos.FirstOrDefault(x => x.ID == 1);

Существует только одна запись, где ID == 1. Должен вернуть эту запись
ID: 1 Имя: Маниш Фамилия: Дубей Электронная почта: xyz@xyz.com

var result = dc.UserInfos.FirstOrDefault(x => x.FName == "Rahul");

Есть несколько записей, где FName == "Rahul". Первая запись должна быть возвращена.
ID: 7 Имя: Рахул Фамилия: Шарма Электронная почта: xyz1@xyz.com

var result = dc.UserInfos.FirstOrDefault(x => x.ID ==13);

Нет записи с идентификатором == 13. Возвращаемое значение равно нулю

Надеюсь, это поможет вам понять, когда использовать First() или FirstOrDefault().

19 голосов
/ 21 июня 2009

Прежде всего, Take - это совершенно другой метод. Он возвращает IEnumerable<T>, а не один T, так что это не так.

Между First и FirstOrDefault следует использовать First, когда вы уверены, что элемент существует, а если нет, то возникает ошибка.

Кстати, если ваша последовательность содержит default(T) элементов (например, null), и вам необходимо различать, что является пустым, и первым элементом является null, вы не можете использовать FirstOrDefault.

13 голосов
/ 04 апреля 2013

Первый:

  • Возвращает первый элемент последовательности
  • Исключение: в результате нет элементов
  • Использовать, когда: когда ожидается более 1 элемента и требуется только первый

FirstOrDefault:

  • Возвращает первый элемент последовательности или значение по умолчанию, если элемент не найден
  • Выдает исключение: только если источник нулевой
  • Использовать, когда: когда ожидается более 1 элемента и требуется только первый элемент. Также вполне возможно, что результат будет пустым

От: http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/

7 голосов
/ 17 сентября 2014

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

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

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

var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
   throw new Exception(string.Format("Can't find customer {0}.", customerId));
}
4 голосов
/ 21 сентября 2016

First ()

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

FirstOrDefault ()

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

3 голосов
/ 21 июня 2009

Я нашел веб-сайт, на котором апперы объяснили необходимость FirstOrDefault
http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/
Если по запросу нет результатов, и вы хотите вызвать First () или Single (), чтобы получить одну строку ... Вы получите исключение «Последовательность не содержит элементов».

Отказ от ответственности: я никогда не использовал LINQ, поэтому мои извинения, если это далеко от цели.

2 голосов
/ 28 августа 2016

Этот тип функции принадлежит элементным операторам. Некоторые полезные операторы элементов определены ниже.

  1. Первый / FirstOrDefault
  2. Последний раз / LastOrDefault
  3. Single / SingleOrDefault

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

  List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };

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

int result = items.Where (item => item == 2) .First ();

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

int result1 = items.Where (item => item == 2) .FirstOrDefault ();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...