Где условие равно true и объект Nullable должен иметь значение - PullRequest
0 голосов
/ 11 октября 2018

Я искал ответ, но не мог найти ничего, чтобы помочь мне.Я получаю эту ошибку

Обнуляемый объект должен иметь значение.

Мой запрос:

from e in dc.tblElements 
where
    e.IsUnique &&
    (e.TypeID == 2) &&     
    (categoryId != null ? e.CategoryId.Value == categoryId.Value : true) &&
    ((e.Name.Contains(keyword)) ||
    (e.Keywords.Contains(keyword)))
select e

Третья строка whereусловие является проблемой (categoryId).Если categoryId имеет значение, оно работает, но не тогда, когда оно null.Однако я заменил эту строку на true, и она также работает.Я не могу понять, в чем здесь проблема.

в моей таблице CategoryId может быть нулевым, поэтому я попытался:

(categoryId.HasValue && e.CategoryId.HasValue ? e.CategoryId.Value == categoryId.Value : true) 

Что я хочу сделать: я хочу выбрать все элементыэтой таблицы в зависимости от условия где.categoryId происходит из выпадающего списка, поэтому, если значение по умолчанию все еще выбрано, когда пользователь делает запрос, я хочу отобразить все элементы независимо от того, какая категория.

Ответы [ 4 ]

0 голосов
/ 11 октября 2018

Попробуйте это:

from e in dc.tblElements 
where
    e.IsUnique &&
    (e.TypeID == 2) &&     
    (categoryId.HasValue && e.CategoryId.Value == categoryId.Value) &&
    ((e.Name.Contains(keyword)) ||
    (e.Keywords.Contains(keyword)))
select e
0 голосов
/ 11 октября 2018

Сделайте CategoryId как обнуляемый тип и попробуйте.

Nullable<int> CategoryId = null;
0 голосов
/ 11 октября 2018

Похоже, вы пытаетесь реализовать "всеобъемлющий" параметр categoryId.Это анти-шаблон в SQL и сильный запах, который может привести к снижению производительности.

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

var query = from e in dc.tblElements 
            where
                e.IsUnique &&
                e.TypeID == 2 &&     
                ( e.Name.Contains(keyword) ||
                  e.Keywords.Contains(keyword) )
            select e;
if (categoryId.HasValue)
{
    query=query.Where(e.CategoryId == categoryId);
}

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

0 голосов
/ 11 октября 2018

У вас должно получиться просто сравнить две переменные:

e.CategoryId == categoryId

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

e.CategoryId == categoryId || !e.CategoryId.HasValue || !categoryId.HasValue

Ваша проблема с вашим утверждением в том, что вы получаете доступ к .Value.Да, если вы запустите код с Linq-To-Objects в памяти, он будет работать, потому что компилятор будет запускать код только одной ветви вашего оператора if (троичный оператор, я знаю, но вы понимаете, что я имею в виду),Но для базы данных необходимо подготовить заявление.Это утверждение должно быть в полном объеме, оно не использует короткое замыкание.Поэтому построитель операторов будет обращаться к обеим вашим веткам, чтобы построить этот оператор для базы данных, и одна из этих ветвей потерпит неудачу, потому что она обращается к .Value, хотя ее нет.

...