【问题标题】:The right way to use lambda expressions in linq在 linq 中使用 lambda 表达式的正确方法
【发布时间】:2014-11-03 16:43:40
【问题描述】:

问题:我想根据我的方法的输入在我的 linq 查询上构造一个动态 where 条件。

假设我的方法接受名字、姓氏和邮政编码。用户可以在我的方法中选择传入其中的一个或多个。

我的 linq 查询如下所示:

var query = (from employee in EmployeeDb.Employees
             select employee)
//Adding firstname to where. Similarly I add other conditions.
if (request.FirstName != string.Empty)
     query = query.Where(c => c.FirstName == request.FirstName);

当我希望我的 SQL 查询条件类似于:

WHERE [Extent6].[LastName] = @p__linq__1 AND [Extent6].[FirstName] = @p__linq__0

我实际看到的是:

 WHERE (([Extent6].[LastName] = @p__linq__0) OR (([Extent6].[LastName] IS NULL) AND (@p__linq__0 IS NULL))) AND (([Extent6].[FirstName] = @p__linq__1) OR (([Extent6].[FirstName] IS NULL) AND (@p__linq__1 IS NULL)))

这显然会导致很多性能问题。我做错了什么?

【问题讨论】:

  • 您是否将 db 列设置为“NOT NULL”?
  • @ErenErsönmez 好点。它们是 NULL。我可以将名称更改为非空值,但其他一些参数可以是空值。因此,如果一个 db 列可以为 NULLable,这意味着 Linq 会自动添加这些检查吗?有没有办法禁用它?
  • 在 EF 6.0+ 中似乎有一个 DbContextConfiguration.UseDatabaseNullSemantics 属性。
  • @ErenErsönmez 非常感谢,到目前为止效果很好。
  • 这是一个非常有趣的想法:stackoverflow.com/questions/5315744/… - Adam Robinson 的解决方案 ;)

标签: c# linq lambda


【解决方案1】:

问题的存在是因为c#和大多数数据库处理空值的不同。在 C# 中,null==null 为 true,而在大多数数据库中,null==null 将返回 false(或未知)。 LINQ 正在尝试编写一个符合 C# 空值思想的 SQL 查询。由于您的字段可以为空,并且您可以询问 Firstname 为空的所有记录,因此这是有道理的。如果您不希望 Firstname 可以为空,则应将其设为 NOT NULL 字段,LINQ 将为您生成更简单的查询。

或者,您可以将上下文对象的 UseDatabaseNullSemantics 属性设置为 true,这将简化您的查询,但您将无法请求 Firstname 为空的记录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多