【问题标题】:Conditional OR has no effect in Linq-to-entities?条件 OR 对 Linq-to-entities 没有影响?
【发布时间】:2013-03-31 21:28:45
【问题描述】:

我今天在我的一个 Linq-To-Entitites 查询中偶然发现了一个 null ref 异常,我想知道这怎么可能。似乎用作 OR 门的条件 OR 在 Linq-To-Entities 中没有效果。我的查询的一个简化示例如下:

from a in db.Articles
where a.Author == "John Doe"
&& (tag == null || a.Tags.Any(t => t.TagName == tag.TagName))
select a;

现在,当 tag 为 NULL 时,where 查询的右侧仍会执行,并且 tag.TagName 上会发生 NULL 引用异常。也许这是因为 Linq-To-Entities 总是将完整的语句翻译成 SQL?

无论如何...如何解决这个问题?

非常感谢:)

【问题讨论】:

    标签: c# linq entity-framework linq-to-entities


    【解决方案1】:
    var query = db.Articles.Where(x => x.Author == "John Doe");
    query = tag == null
        ? query
        : query.Where(x => x.TagName == tag.TagName);
    

    或:

    var query = from a in db.Articles
                where a.Author == "John Doe"
                select a;
    
        query = tag == null
            ? query
            : from a in query
                where a.Tags.Any(t => t.TagName == tag.TagName)
                select a;
    

    我个人觉得第一个更干净

    【讨论】:

    • 非常感谢,马特!我现在很好奇生成的 SQL 会是什么样子……会尝试一下 :)
    【解决方案2】:

    想想sql。 Linq 将您的代码作为一个整体转换为 sql 查询,将“外部”对象作为参数传递并评估它们。这就是为什么它在评估您的 null 对象时失败的原因。

    最好根据条件逐位构造 linq 查询,以减少结果查询中不必要的代码数量,因此最好拆分查询:

    var query = db.Articles.Where(x => x.Author == "John Doe");
    if( tag != null)
      query = query.Where(x => x.TagName == tag.TagName);
    

    因为您的查询将在选择时被评估和执行,所以欢迎您添加更多条件而不必担心多个请求。

    【讨论】:

    • 感谢 Dima,还确认了 Linq-To-Entities 将整个查询直接转换为 SQL 并且不应用任何 C# 逻辑的行为。
    猜你喜欢
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 2011-05-14
    相关资源
    最近更新 更多