C# 在linq中使用lambda表达式的正确方法

C# 在linq中使用lambda表达式的正确方法,c#,linq,lambda,C#,Linq,Lambda,问题:我想基于方法的输入在linq查询上构造一个动态where条件 假设我的方法接受名字、姓氏和zipcode。用户可以选择在我的方法中传入一个或多个 我的linq查询如下所示: var query = (from employee in EmployeeDb.Employees select employee) //Adding firstname to where. Similarly I add other conditions. if (request.Firs

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

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

我的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条件类似于:

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)))

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

问题的存在是因为c#和大多数数据库处理空值的方式不同。在C#中,null==null为true,而在大多数数据库中,null==null将返回false(或unknown)。LINQ正试图编写一个与C#的空值思想相匹配的SQL查询。因为您的字段是可空的,并且您可以请求Firstname为空的所有记录,所以这是有意义的。如果您不希望Firstname为空,那么应该将其设置为非空字段,LINQ将为您生成一个更简单的查询


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

您是否已将db列设置为“not null”?@ErenErsönmez Great point。它们是空的。我可以将名称更改为非null,但其他一些参数可以为null。那么,如果一个db列可以为null,这意味着Linq将自动添加这些检查?没有办法禁用它?看起来EF 6.0+中有一个
DbContextConfiguration.UseDatabaseNullSemantics
属性。@ErenErsönmezThanks很多,到目前为止效果非常好。这里有一个非常有趣的想法:-Adam Robinson的解决方案;)