Использование FirstOrDefault () в запросе - PullRequest
4 голосов
/ 03 ноября 2011

Есть ли способ использовать FirstOrDefault() внутри сложного запроса, но не генерировать исключение, если он возвращает нулевое значение?

Мой запрос:

contex.Table1.Where(t => t.Property == "Value").FirstOrDefault()
             .Object.Table2.Where(t => t.Property2 == "Value2").FirstOrDefault();

Если запрос наПервая таблица (Table1) не возвращает объект, код выдает исключение.Есть ли способ заставить его возвращать только ноль?

Ответы [ 3 ]

4 голосов
/ 03 ноября 2011

Попробуйте SelectMany на Table2, без промежуточного FirstOrDefault():

context.Table1.Where(t1 => t1.Property1 == "Value1")
              .SelectMany(t1 => t1.Table2.Where(t2 => t2.Property2 == "Value2"))
              .FirstOrDefault();

Также вы можете использовать SQL Profiler для проверки SQL, отправляемого EF.Я полагаю, что запрос, составленный в вашем вопросе, приведет к отправке двух запросов в базу данных;по одному на каждого FirstOrDefault().

1 голос
/ 03 ноября 2011

Только первый запрос с Where является запросом к базе данных.Как только вы примените «жадный» оператор, такой как FirstOrDefault, запрос будет выполнен.Второй запрос выполняется в памяти.Если Object.Table2 является коллекцией (что, по-видимому, и есть) и у вас не включена отложенная загрузка, ваш код вылетает, потому что коллекция null.Если у вас включена отложенная загрузка, второй запрос выполняется без вывода сообщений для загрузки коллекции - коллекция complete и фильтр выполняются в памяти.

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

1 голос
/ 03 ноября 2011

Вы можете создать свою собственную вспомогательную функцию, которая принимает IEnumerable

public static TSource CustomFirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
    return source.FirstOrDefault() ?? new List<TSource>();
}

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

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