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字符越少)