Відповіді:
Ось огляд різних методів:
Find () - коли ви хочете отримати товар за первинним ключем. Це повернеться до нуля, якщо він не зможе знайти елемент. Він перегляне контекст перед тим, як перейти до бази даних (на що вказував Ярон у коментарях), що може бути важливим фактором ефективності, якщо вам потрібно отримати одне і те ж об'єкт кілька разів, поки живий той самий контекст.
Single () - коли ви очікуєте, що запит буде повернуто точно одним елементом. Це призведе до виключення, якщо запит не повертає рівно один елемент.
SingleOrDefault () - коли ви очікуєте, що за запитом буде повернуто нуль або один елемент (тобто ви не впевнені, чи існує елемент із заданим ключем). Це призведе до виключення, якщо запит не поверне нуль або один елемент.
Перший () - коли ви очікуєте, що один або кілька елементів будуть повернуті запитом, але ви хочете отримати доступ лише до першого елемента у вашому коді (замовлення може бути важливим у запиті тут). Це призведе до виключення, якщо запит не повертає хоча б один елемент.
FirstOrDefault () - коли ви очікуєте, що за запитом буде повернуто нуль або більше елементів, але ви хочете отримати доступ лише до першого елемента у вашому коді (тобто ви не впевнені, чи існує елемент із заданим ключем)
Sales.OrderByDescending(s => s.TotalValue).First();
Single
або SingleOrDefault
буде запит на 2 записи (обмеження 2), в той час як First
або FirstOrDefault
буде запит на 1 (обмеження 1).
Я завжди схильний використовувати FirstOrDefault
. Якщо ви дійсно хочете бути вимогливими до продуктивності, тоді вам варто скористатися FirstOrDefault
в EF. Під обкладинками SingleOrDefault
використовується запит top (2), оскільки він повинен перевірити, чи є другий рядок, який відповідає критеріям, і якщо він є, він викидає виняток. В основному SingleOrDefault
ви говорите, що ви хочете викинути виняток, якщо ваш запит повертає більше 1 запису.
FirstOrDefault
та SingleOrDefault
бути значущим? Я б сказав, що це передчасна оптимізація в більшості випадків.
Single()
або SingleOrDefault()
коли повертаю те, що повинно існувати лише одне . Причиною цього я є виявлення помилок, роблячи погано написані запити, які повертають більше, ніж повинні, не вдається. Принаймні, на мій погляд, це допоможе підтримувати дані в системі. Звичайно, це повільніше, але я б здогадався, що це не набагато повільніше, і я готовий заплатити цю ціну.
Це дійсно дуже просто: Single
повертає один елемент і кидає виняток, якщо його немає або більше одного. First
поверне перший елемент або кине, коли його немає. FirstOrDefault
поверне перший елемент або поверне значення за замовчуванням (що є null
у випадку, якщо даний тип є еталонним типом), коли його немає.
Це поведінка, якою повинен володіти API. Однак зауважте, що основна реалізація може мати іншу поведінку. Хоча Entity Framework підкоряється цьому, O / RM на зразок LLBLGen також може повертатися null
при дзвінках, First
що є дуже дивною річчю. Це було дуже дивне (і вперте) рішення дизайнера IMO.
Single
чітко виражає, що ви очікуєте, що результат матиме лише один елемент.
Чотири методи мають своє місце; Хоча у вас дійсно є лише дві різні операції.
Версія xxxxOrDefault () просто додає "Я не хочу вважати порожній результат набору винятковою обставиною".
З іншого боку, ви можете розділити ці методи за основною логікою, наприклад:
Деякі відомості про ефективність, особливо у другому випадку, можна переглянути тут: https://msdn.microsoft.com/en-us/data/hh949853.aspx?f=255&MSPPError=-2147217396#3
Крім того, в першій групі ви можете визначити складні запити, але за допомогою методу Find () ви можете надати лише ключ сутності для пошуку.
Single () і SingleOrDefault () зазвичай використовується для унікальних ідентифікаторів, таких як ідентифікатори, тоді як First () або FirstOrDefault () зазвичай використовуються для запиту, який може мати декілька результатів, але вам потрібно лише "Top 1" .
Single () або First () буде кидати виняток, якщо результат не повертається, SingleOrDefault () та FirstOrDefault () ловить виняток і повертає null або default (ResultDataType).