1

我有一个接收类别 id 的方法,后跟两个默认为 null 的可选字符串参数。

我尝试使用其他关于 SO 的问题的类似答案,但到目前为止没有任何帮助。

我试图让 linq to EF 查询按如下方式工作:

如果任一可选参数有值,则使用该值,否则使用 Is Null。

如果两个可选参数都存在,则将它们用作查询的一部分,或者仅在提供的 eis 上使用其中一个。但如果没有添加参数,则只需使用类别 id。

db 中的两个可选参数都标记为可为空。

这是不起作用的代码:

          from c in dtx.Categories
          where c.CategoryId == CatId
         && (string.IsNullOrEmpty(param1) ? c.Param1 == null : c.Param1 == param1)
         && (string.IsNullOrEmpty(param2) ? c.Param2 == null : c.Param2 == Param2)
        select c

尝试二:

          from c in dtx.Categories
          where c.CategoryId == CatId
          && (c.Param1 == null ? c.Param1 == null : c.Param1 == param1)
          && (c.Param2 == null ? c.Param2 == null : c.Param2 == param2)
          select c

不会抛出任何错误,但两个查询始终返回零结果,除非两个参数都存在。

我尝试过的帖子之一: 如何在实体框架中查询空值?

4

4 回答 4

2

据我所知,问题看起来像查询的条件写得不正确。让我们检查一下将附加一个示例的内容:

数据:

Id = 1, Param1 = null, Param2 = null
Id = 2, Param1 = 'a'   param2 = null
Id = 3, Param1 = null, Param2 = 'b'
Id = 4, Param1 = 'a'   param2 = 'c'

使用当前查询和提出的其他解决方案,您只会得到 Id 1。您的条件是:如果 Param1 为 Null 且 c.Param1(存储的值)为 null 或 c.Param1 等于 Param1 值。

您需要的是一个条件:如果 Param1 为 Null 或 c.Param1 等于 Param1 值。

如果您使用此查询,您将始终得到您的结果。

from c in dtx.Categories
where c.CategoryId == CatId
    && (string.IsNullOrEmpty(param1) || c.Param1 == param1)
    && (string.IsNullOrEmpty(param2) || c.Param2 == param2)
select c
于 2012-05-24T18:36:36.077 回答
1

第三次编辑运气,也许我这次读到了这个问题:)

var p1 = string.IsNullOrEmpty(param1) ? null : param1;
var p2 = string.IsNullOrEmpty(param2) ? null : param2;

var query = dtx.Categories.Where(c => c.CategoryId == CatId);
if (p1 != null || p2 != null) {
    query = query.Where(c => c.Param1 == p1 && c.Param2 == p2);
}
于 2012-05-24T17:59:45.130 回答
0

您应该明确展开检查,两者都是null或它们匹配

((string.IsNullOrEmpty(param1) && c.Param1 == null) || (c.Param1 == param1))

编辑:刚刚测试过,你检查null或不检查SQL是否相同并不重要,所以就这样做

from c in dtx.Categories 
    where c.CategoryId == CatId 
       && (c.Param1 == param1) 
       && (c.Param2 == Param2) 
select c 
于 2012-05-24T17:58:21.820 回答
0

问题是当你写

from ... where c.Param1 == null ...

LINQ 将其转换为相同的 SQL 表达式:

SELECT ... FROM ... WHERE Param1 = null ...

但你需要这个:

SELECT ... FROM ... WHERE Param1 IS NULL ...

所以这里正确的解决方案是

from c in dtx.Categories
where c.CategoryId == CatId && 
     (param1 == null ? !c.Param1.HasValue : c.Param1.Value == param1) && 
     (param2 == null ? !c.Param2.HasValue : c.Param2.Value == param2)
select c
于 2013-10-24T10:55:51.733 回答