4

拿着这个:

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

someObjectList.Where(x => x.SomeItem1 == (item1 ?? x.SomeItem1)
                       && x.SomeItem2 == (item2 ?? x.SomeItem2) 
                    );

wheresomeObjectList不为空,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) 
                             );
}

所有的 ID 都是Nullable<long>.

编辑:

SQL 探查器:

SELECT *
  FROM [dbo].[CampaignSchedulePlacements] AS [Extent5]
WHERE ([Extent5].[MediaCategoryFormatID] = [Extent5].[MediaCategoryFormatID]) AND ([Extent5].[MediaCategorySizeID] = [Extent5].[MediaCategorySizeID])

注意:清理了`SQL.

4

1 回答 1

5

在 SQL 中,NULL 不等于 NULL。

您可以将 NULL 解释为:“有价值,但我不知道它是什么”。因此,如果您要比较两个 NULL 值,您实际上是在问“第一个未知值是否等于第二个未知值?” 当然,没有理由假设它们是,所以 SQL 会说“不”。

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

更新:

条件

([Extent5].[MediaCategoryFormatID] = [Extent5].[MediaCategoryFormatID]) 

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

这回答了“为什么它什么都不返回?”这个问题。

然而,另一个问题浮现在脑海中:为什么实体框架会从这个 linq 查询中生成那个 SQL?

恐怕 linq to entity 并不完全以其 SQL 生成的质量而闻名,而这个案例似乎证实了这一点。您可能会考虑使用 Linq to SQL。即使从长远来看,这似乎是一条死胡同,但当前的实现如果比 linq to entity 好得多。

无论哪种情况,您是否尝试过类似

someObjectList.Where(x => 
    !item1.hasValue || 
    x.SomeItem1.HasValue && x.SomeItem1.Value == item1.Value)

确保也验证在分析器下,linq to entity 也可能会搞砸。

于 2012-07-21T17:51:54.733 回答