LINQ Single vs First

LINQ:

Является ли более эффективным использование оператора Single() над First() когда я точно знаю, что запрос вернет одну запись ?

Есть ли разница?

10 Solutions collect form web for “LINQ Single vs First”

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

Я знаю, что другие писали, почему вы используете то или другое, но я подумал, что я проиллюстрирую, почему вы НЕ должны использовать его, когда имеете в виду другого.

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

Возьмем, например, таблицу, в которой Customers хранятся на разных языках, используя комбинированный ключ ( ID , Lang ):

 DBContext db = new DBContext(); Customer customer = db.Customers.Where( c=> c.ID == 5 ).First(); 

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

Поскольку вы намерены вернуть единому Customer используйте Single() ;

Следующее заставило бы исключение (это то, что вы хотите в этом случае):

 DBContext db = new DBContext(); Customer customer = db.Customers.Where( c=> c.ID == 5 ).Single(); 

Затем вы просто ударились о лоб и сказали себе … ООПС! Я забыл языковое поле! Ниже приведена правильная версия:

 DBContext db = new DBContext(); Customer customer = db.Customers.Where( c=> c.ID == 5 && c.Lang == "en" ).Single(); 

First() полезен в следующем сценарии:

 DBContext db = new DBContext(); NewsItem newsitem = db.NewsItems.OrderByDescending( n => n.AddedDate ).First(); 

Он вернет ОДИН объект, и поскольку вы используете сортировку, это будет самая последняя запись, которая будет возвращена.

Использование Single() когда вы чувствуете, что должно явно возвращать 1 запись, поможет вам избежать логических ошибок.

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

Оба будут InvalidOperationException исключение InvalidOperationException если коллекция пуста. В качестве альтернативы вы можете использовать SingleOrDefault() . Это не вызовет исключения, если список пуст

Между этими двумя методами существует тонкая смысловая разница.

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

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

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

Один()

Возвращает один конкретный элемент запроса

При использовании : Если ожидается ровно 1 элемент; не 0 или более 1. Если список пуст или имеет более одного элемента, он будет генерировать исключение «Последовательность содержит более одного элемента»,

SingleOrDefault ()

Возвращает один конкретный элемент запроса или значение по умолчанию, если результат не найден

Когда используется : когда ожидается 0 или 1 элемент. Он будет генерировать исключение, если список содержит 2 или более элементов.

Первый()

Возвращает первый элемент запроса с несколькими результатами.

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

FirstOrDefault ()

Возвращает первый элемент списка с любым количеством элементов или значением по умолчанию, если список пуст.

Когда используется : когда ожидается несколько элементов, и вы хотите только первый. Или список пуст, и вы хотите, чтобы значение по умолчанию для указанного типа было таким же, как и по default(MyObjectType) . Например: если тип списка – это list он вернет первое число из списка или 0, если список пуст. Если это list , он вернет первую строку из списка или null, если список пуст.

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

Лично я всегда использую First ().

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

Оба они эффективны, возьмите первый элемент. First() немного более эффективен, потому что он не мешает проверить, есть ли второй элемент.

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

Что касается производительности: мы с коллегой обсуждали производительность Single vs First (или SingleOrDefault vs FirstOrDefault), и я спорил в том смысле, что First (или FirstOrDefault) будет быстрее и повышает производительность (я все о создании нашего приложения беги быстрее).

Я прочитал несколько сообщений о переполнении стека, которые обсуждают это. Некоторые говорят, что есть небольшой прирост производительности, используя First вместо Single. Это связано с тем, что First просто вернул первый элемент, а Single должен проверить все результаты, чтобы убедиться, что нет дубликата (то есть: если он нашел элемент в первой строке таблицы, он все равно сканирует каждую другую строку до убедитесь, что нет второго значения, соответствующего условию, которое затем выдало бы ошибку). Я чувствовал, что я нахожусь на твердой почве, когда «Первый» был быстрее, чем «Одиночный», поэтому я решил доказать это и поставил дискуссию на покой.

Я установил тест в своей базе данных и добавил 1 000 000 строк идентификатора UniqueIdentifier Foreign UniqueIdentifier Info nvarchar (50) (заполненный строками чисел «0» до «999,9999»,

Я загрузил данные и установил идентификатор в качестве поля первичного ключа.

Используя LinqPad, моя цель состояла в том, чтобы показать, что если вы искали значение «Foreign» или «Info», используя Single, это было бы намного хуже, чем использование First.

Я не могу объяснить полученные результаты. Почти в каждом случае использование Single или SingleOrDefault было несколько быстрее. Это не имеет для меня никакого логического смысла, но я хотел бы поделиться этим.

Пример: я использовал следующие запросы:

 var q = TestTables.First(x=>x.Info == "314638") ; //Vs. Var q = TestTables.Single(x=>x.Info =="314638") ; //(this was slightly faster to my surprise) 

Я пробовал аналогичные запросы в поле «Foreign», которое не было проиндексировано, думая, что будет доказано, что First быстрее, но Single всегда был немного быстрее в моих тестах.

Они разные. Оба они утверждают, что результирующий набор не пуст, но single также утверждает, что результат не более 1. Я лично использую Single в тех случаях, когда я ожидаю, что результат будет 1, потому что получение более одного результата обратно является ошибкой и, вероятно, должно рассматриваться как таковое.

Вы можете попробовать простой пример, чтобы получить разницу. Исключение будет выбрано в строке 3;

  List records = new List{1,1,3,4,5,6}; var record = records.First(x => x == 1); record = records.Single(x => x == 1); 

Многие люди, которых я знаю, используют FirstOrDefault (), но я предпочитаю использовать SingleOrDefault () больше, потому что часто это будет некоторая несогласованность данных, если их было несколько. Однако это связано с LINQ-to-Objects.

  • LINQ Distinct () для определенного свойства
  • XDocument, содержащий пространства имен
  • Зачем использовать AsQueryable () вместо List ()?
  • Как сделать SQL как% в Linq?
  • Как получить индекс с помощью LINQ?
  • Linq int to string
  • Различия между IQueryable, List, IEnumerator?
  • Получение имени свойства из выражения lambda
  • C # - код для заказа по свойству с использованием имени свойства в виде строки
  • Пейджинг с LINQ для объектов
  • Как я могу получить каждый n-й элемент из списка ?
  • Interesting Posts

    Поиск в каталоге в командной строке Windows показывает неправильный вывод

    Загрузите произвольный файл в Google Chrome

    Преобразование VS2012 в VS2010

    Должен ли я использовать .done () и .fail () для нового кода jQuery AJAX вместо успеха и ошибки

    Как включить EF-миграции для разных контекстов для разделения баз данных?

    Настройка виртуального ПК (виртуального окна) в качестве веб-сервера

    MongoDB: уникальный индекс для свойства элемента массива

    Как определить, какой тип JRE установлен – 32 бит против 64 бит

    Как транслировать ТВ / Фильмы / Музыка через Интернет на различные устройства с домашнего сервера?

    Как преобразовать фотографию в черно-белое изображение с помощью ImageMagick?

    Должна ли загрузка файла на DSL убивать скорость загрузки?

    Внешний жесткий диск не пуст, но файлы не отображаются

    QEMU с пропуском GPU не запустится

    Где можно быстро найти, какое максимальное разрешение поддерживает видеокарта?

    Как включить этот обратный вызов в promise, используя async / wait?

    Давайте будем гением компьютера.