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

时间:2009-07-14 15:21:59

标签: 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
                   where mt.PARENT_KEY == id
                   select new { mt.NAME };

为什么?

3 个答案:

答案 0 :(得分:20)

经过一番谷歌搜索后,我找到了答案:

ref #1

ref #2

int? id = null;
var list = from mt in db.MY_TABLE
           where object.Equals(mt.PARENT_KEY, id)  //use object.Equals for nullable field
           select new { 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))

答案 1 :(得分:5)

一种可能性 - 如果mt.PARENT_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类型?

答案 2 :(得分:1)

这绝对是C#和SQL的问题,它有如何比较空值的不同概念 - 这个问题在此之前已经解决过:

Compare nullable types in Linq to Sql