Код Linq для выбора одного элемента

Я нахожу, что пишу много кода, подобного этому, чтобы выбрать один элемент, который соответствует

var item = (from x in Items where x.Id == 123 select x).First();

Есть ли более чистый способ сделать это или это будет кратким, как я собираюсь получить?

РЕДАКТИРОВАТЬ: Должен сказать "Чистый способ с использованием синтаксиса linq". Я уже знал о синтаксисе лямбда, и он начинает выглядеть так, как будто это единственный способ. Я получил некоторую полезную информацию, хотя, спасибо всем, кто ответил.

Ответ 1

Зависит от того, насколько вам нравится синтаксис запроса linq, вы можете использовать методы расширения напрямую:

var item = Items.First(i => i.Id == 123);

И если вы не хотите бросать ошибку, если список пуст, используйте FirstOrDefault, который возвращает значение по умолчанию для типа элемента (null для ссылочных типов):

var item = Items.FirstOrDefault(i => i.Id == 123);

if (item != null)
{
    // found it
}

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

Из семейства First() и Single(), где они бросают:

  • First() - бросает, если пуст/не найден, не бросает, если дубликат
  • FirstOrDefault() - возвращает значение по умолчанию, если пусто/не найдено, не выбрасывает, если дубликат
  • Single() - бросает, если пуст/не найден, бросает, если существует дубликат
  • SingleOrDefault() - возвращает значение по умолчанию, если пусто/не найдено, выбрасывает, если существует дубликат

Ответ 2

FirstOrDefault или SingleOrDefault может быть в зависимости от вашего сценария, и хотите ли вы обрабатывать нулевое или большее совпадение:

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

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

имеется более одного элемента,

Я не знаю, как это работает в запросе linq 'from', но в синтаксисе лямбда выглядит так:

var item1 = Items.FirstOrDefault(x => x.Id == 123);
var item2 = Items.SingleOrDefault(x => x.Id == 123);

Ответ 3

Это предпочтительные методы:

var item = Items.SingleOrDefault(x => x.Id == 123);

или

var item = Items.Single(x => x.Id == 123);

Ответ 4

Это можно свести к минимуму.

var item = Items.First(x => x.Id == 123);

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

Одиночные/SingleOrDefault заслуживают внимания, но только если вы хотите итерации по всей коллекции и убедитесь, что совпадение уникально в дополнение к выбору этого соответствия. First/FirstOrDefault просто займет первое совпадение и уйдет, независимо от того, сколько фактически существует дубликатов.

Ответ 5

Просто, чтобы облегчить кому-то жизнь, запрос linq с выражением лямбда

(from x in Items where x.Id == 123 select x).FirstOrDefault();

приводит к SQL-запросу с select top (1).

Ответ 6

Вы можете использовать синтаксис метода расширения:

var item = Items.Select(x => x.Id == 123).FirstOrDefault();

Кроме того, я не уверен, насколько более кратким вы можете получить, не создавая собственных специализированных методов "First" и "FirstOrDefault".

Ответ 7

Я расскажу вам, что сработало для меня:

int id = int.Parse(insertItem.OwnerTableView.DataKeyValues[insertItem.ItemIndex]["id_usuario"].ToString());

var query = user.First(x => x.id_usuario == id);
tbUsername.Text = query.username;
tbEmail.Text = query.email;
tbPassword.Text = query.password;

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