Where condition equal true 和 Nullable 对象必须有一个值

Where condition equal true and Nullable object must have a value

我一直在寻找答案,但找不到任何可以帮助我的东西。我得到这个错误

Nullable object must have a value.

我的要求是:

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 替换了这一行,它也能正常工作。我不明白这里有什么问题。

在我的 table CategoryId 中可以为空,所以我尝试了:

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

我想做什么:我想 select 这个 table 的所有元素取决于 where 条件。 categoryId 来自下拉菜单,因此如果在用户发出请求时默认值仍然是 selected,我想显示所有元素,无论类别是什么。

您应该只比较两个变量就可以了:

e.CategoryId == categoryId

如果你想对一个 NULL 进行特殊处理,可能是因为你希望它是 NULL 匹配 所有内容 而不是另一个 NULL 的特殊情况,你可以添加:

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

你的陈述有问题是你访问了.Value。是的,如果你 运行 内存中带有 Linq-To-Objects 的代码,它会起作用,因为编译器只会 运行 你的 if 语句的一个分支的代码(三元运算符,我知道,但你明白我的意思)。但是对于数据库来说,需要准备一条语句。该声明需要完整存在,它不使用任何短路。因此,语句构建器 访问您的两个分支来为数据库构建该语句,并且其中一个分支将失败,因为它访问 .Value 尽管有 none。

将 CategoryId 设置为可空类型并尝试。

Nullable<int> CategoryId = null;

您似乎正在尝试实施 "catch-all" 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);
}

您可以使用它在运行时添加多个条件

试试这个:

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