Null coalesce在LINQ查询中不起作用

Wil*_*lem 4 .net c# linq linq-to-entities entity-framework-4.3

拿着这个:

int? item1 = null;
int? item2 = null;

someObjectList.Where(x => x.SomeItem1 == (item1 ?? x.SomeItem1)
                       && x.SomeItem2 == (item2 ?? x.SomeItem2) 
                    );
Run Code Online (Sandbox Code Playgroud)

someObjectList不空,SomeItem1并且SomeItem2null在列表中的所有对象.

为什么一无所获?

编辑:

我的代码:

public void GetPlacementsByMaterial(long clientMaterialID)
{
    ClientMaterial clientMaterial = ((ApplicationEntityModel)NavigationItem.ObjectContext).ClientMaterial.FirstOrDefault(x => x.ClientMaterialID == clientMaterialID);

    var list = GetPlacementList(supplier, mediaSpace);

    PlacementsList = list.Where(x => x.MediaCategoryFormatID == (clientMaterial.MediaCategoryFormatID ?? x.MediaCategoryFormatID)
                                                && x.MediaCategorySizeID == (clientMaterial.MediaCategorySizeID ?? x.MediaCategorySizeID) 
                             );
}
Run Code Online (Sandbox Code Playgroud)

所有ID都是Nullable<long>.

编辑:

SQL事件探查器:

SELECT *
  FROM [dbo].[CampaignSchedulePlacements] AS [Extent5]
WHERE ([Extent5].[MediaCategoryFormatID] = [Extent5].[MediaCategoryFormatID]) AND ([Extent5].[MediaCategorySizeID] = [Extent5].[MediaCategorySizeID])
Run Code Online (Sandbox Code Playgroud)

注意:清理了`SQL.

Kri*_*ten 5

在SQL中,NULL不等于NULL.

您可以将NULL解释为含义:"有价值,但我不知道它是什么".因此,如果你要比较两个NULL值,你真的会问"第一个未知值是否等于第二个未知值?" 当然,没有理由认为它们是,所以SQL会说"不".

我假设这是导致你的问题.您可以通过查看生成的实际SQL来验证.如果它使用SQL =运算符,这确实是问题所在.您可以通过在数据库工具中运行SQL来验证这一点,例如SQL Management Studio,以防您使用SQL Server.

更新:

条件

([Extent5].[MediaCategoryFormatID] = [Extent5].[MediaCategoryFormatID]) 
Run Code Online (Sandbox Code Playgroud)

[Extent5]时确实会返回false.[MediaCategoryFormatID]为NULL.

这回答了"它为什么没有返回什么?"的问题.

但是,另一个问题浮出水面:为什么实体框架会从这个linq查询生成SQL?

我担心linq到实体并不完全以其SQL生成的质量而闻名,这种情况似乎证实了这一点.你可能会考虑Linq to SQL.从长远来看,即使这似乎是一条死路,但目前的实施情况如果比实体更好.

在任何一种情况下,你尝试过类似的东西

someObjectList.Where(x => 
    !item1.hasValue || 
    x.SomeItem1.HasValue && x.SomeItem1.Value == item1.Value)
Run Code Online (Sandbox Code Playgroud)

确保在分析器下验证,但实体的linq也可能搞乱它.

  • @Willem和Kris:这个行为实际上是LINQ to Entities中的一个老错误:http://stackoverflow.com/questions/682429/how-can-i-query-for-null-values-in-entity-framework`null在.NET中,== null`是'true`所以它不能直接转换为SQL中的`NULL = NULL`,而不是'true`.它已针对.NET 4.5进行了修复,因此您不再需要上面的解决方法以及.NET 4.5中链接问题的答案. (4认同)