Entity Framework - правильный способ проверки отдельных записей перед их использованием - PullRequest
9 голосов
/ 26 января 2010

Чтобы получить СПИСОК записей, я обычно делаю что-то вроде:

var efCompany = from a in _dbRiv.Company where a.CompanyId == companyFeedInfo.CompanyId select a;

Чтобы получить одну запись, когда я знаю, что использую ПК для ее извлечения, я использую что-то вроде:

var efCompany = (from a in _dbRiv.Company where a.CompanyId == companyFeedInfo.CompanyId select a).First();

Теперь, используя подход с одной записью, если PK является ошибочным значением (как это целенаправленно находится в тестировании), во 2-й строке выдается ошибка.

Каков лучший метод способа получения одной записи и работы с ней?

Ответы [ 4 ]

21 голосов
/ 27 января 2010

Используйте SingleOrDefault, если вы ожидаете 0 или 1, или FirstOrDefault, если вам просто нужна первая запись из потенциально большого количества, но вы можете справиться с 0. Оба вернут значение по умолчанию для типа (обычно ноль), еслирезультатов нет.

Кстати, подобные запросы обычно более читабельны (IMO) без с использованием выражения запроса, поэтому вы можете получить что-то вроде:

var efCompany = _dbRiv.Company
                      .Where(a => a.CompanyId == companyFeedInfo.CompanyId)
                      .SingleOrDefault();

if (efCompany != null)
{
    // Use it
}
else
{
    // Report to user, or whatever
}

Выражения запроса хороши, когда вы используете несколько операторов или выполняете относительно сложные вещи, такие как объединения - но если у вас просто есть предложение where или просто естьпроекция, эта «точечная нотация» является более простой IMO.Это также работает лучше, когда вам нужно вызвать метод, такой как FirstOrDefault в конце.

7 голосов
/ 27 января 2010

Обратите внимание, что SingleOrDefault() и FirstOrDefault() не позволят вам указать значение по умолчанию.

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

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

2 голосов
/ 02 октября 2012
var efCompany = _dbRiv.Company
                  .SingleOrDefault(a => a.CompanyId == companyFeedInfo.CompanyId);

if (efCompany != null)
{
    // Use it
}
else
{
    // Report to user, or whatever
}
0 голосов
/ 01 января 2016

Вы также можете использовать

_dbRiv.Company.find(#id) 

если вы ищете запись без включенных моделей.

или

_dbRiv.Company.FirstOrDefault(x => x.Id == #id);

Я рекомендую FirstOrDefault вместо SingleOrDefault из-за производительности. С SingleOrDefault ему нужно просканировать всю таблицу и убедиться, что есть только одна запись с идентификатором. С FirstOrDefault он может просто идти, пока не найдет этот идентификатор, а затем остановиться. На большом столе это сэкономит вам небольшое количество времени с каждым запросом.

Также вы можете использовать AsNoTracking для улучшения потребления памяти, если вам не нужно отслеживать какие-либо изменения, сделанные в модели. Например, если вы возвращаете его через запрос на отдых без вызова save.

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