Linq to sql LINQ到SQL-where子句中的可空类型

Linq to sql LINQ到SQL-where子句中的可空类型,linq-to-sql,Linq To Sql,我有一个表,它的列有空值。。。当我尝试查询该列为空的记录时: 这项工作: var list = from mt in db.MY_TABLE where mt.PARENT_KEY == null select new { mt.NAME }; 这并不是: int? id = null; var list = from mt in db.MY_TABLE

我有一个表,它的列有空值。。。当我尝试查询该列为空的记录时:

这项工作:



        var list = from mt in db.MY_TABLE
                   where mt.PARENT_KEY == null
                   select new { mt.NAME };

这并不是:



        int? id = null;
        var list = from mt in db.MY_TABLE
                   where mt.PARENT_KEY == id
                   select new { mt.NAME };


为什么?

一种可能性-如果
mt.PARENT\u KEY
属于其他类型(例如
long?
),则会涉及转换

如果您可以显示每个案例中涉及的类型和生成的查询,这将有所帮助

编辑:我想我有一个想法

这可能是因为SQL和C#对等式在null中的含义有不同的理解。试试这个:

where (mt.PARENT_KEY == id) || (mt.PARENT_KEY == null && id == null)
如果是这样的话,那么这是一个非常丑陋的角落案件,但我能理解为什么会这样做。。。如果生成的SQL只是使用

WHERE PARENT_KEY = @value
那么,当值为null时,这将不起作用-它需要:

WHERE (PARENT_KEY = @value) OR (PARENT_KEY IS NULL AND @value IS NULL)
这是后一个LINQ查询应该生成的


出于兴趣,你为什么选择

select new { mt.NAME }
而不仅仅是

select mt.NAME

?)为什么您想要一个匿名类型序列而不是字符串序列(或任何类型的
NAME
呢?

这肯定是C#和SQL在如何比较空值方面有不同概念的问题-这个问题以前已经在这里讨论过了:


在谷歌搜索了一番之后,我找到了答案:

int?id=null;
var list=来自db.MY_表中的mt
其中object.Equals(mt.PARENT_KEY,id)//将object.Equals用于可空字段
选择新的{mt.NAME};
此LINQ呈现为SQL,如下所示:

((mt.PARENT_KEY IS NULL) AND (@id IS NULL)) 
OR ((mt.PARENT_KEY IS NOT NULL) AND (@id IS NOT NULL) AND (mt.PARENT_KEY = @id))

你试过查看每种情况下生成的SQL吗?生成的代码中mt.PARENT\u键的类型是什么?可以为NULL,可以为NULL?我已经更新了Nick的答案,以反映Object.Equals如何呈现SQL。在你看来,额外的
(mt.PARENT\u键不为NULL)和(@id不为NULL)
第2行多余?这是您的答案所建议的。(LINQ字符越多,SQL字符越少)