使用:Entity Framework 4.3.1,MVC 4
示例数据库记录(例如):
Id Height 1 null 2 2.1
为什么第一个陈述会带来零结果:
decimal? scannedItemHeight = default(decimal?);
(from st in Stocks
where st.Height == scannedItemHeight
select st.Id).ToList();
但是此语句返回记录Id 1:
(from st in Stocks
where st.Height == null
select st.Id).ToList();
如果scanningItemHeight为null,我只想匹配高度为null的值。
我只想返回第一条记录,Id 1。
更新 我最终使用了:
st.Height == scannedItemHeight || (scannedItemHeight == null && st.Height == null)
答案 0 :(得分:3)
我之前确实看到过一些奇怪的LINQ行为,因为SQL处理空值的方式与C#处理空值的方式不同。在C#中,如果a == b
和a
都为空,则b
为真,而在SQL中,它们不是......而是您必须故意检查无效。我会尝试:
var temp = (from st in Stocks
where st.Height == scannedItemHeight || (scannedItemHeight == null && st.Height == null)
select st.Id).ToList();
或者以不同方式构建查询:
var filtered = scannedItemHeight == null
? Stocks.Where(st => st.Height == null)
: Stocks.Where(st => st.Height == scannedItemHeight);
var temp = filtered.Select(st => st.Id).ToList();
答案 1 :(得分:3)
那是因为在第一种情况下数据库查询类似于
where Height = @param1 ...
而在第二种情况下将是
where Height is null
第一个查询将不返回任何结果,因为@param1将为null,并且没有行可以匹配此类条件。
要点是从C#的角度来看这些查询是等价的,但是从sql的角度看它们不是:你应该在sql中使用IS NULL(或IS NOT NULL)来检查空值。
如何修复取决于您的参数为null时要执行的操作。在您的情况下:使用Jon Skeet的回答。
如果有人想要忽略参数而根本没有过滤(很常见的情况,例如当参数代表用户在某些字段中的输入时,当没有任何内容输入时 - 没有任何可过滤的内容),那么做:
where scannedItemHeight == null || st.Height == scannedItemHeight
将在sql中,如
where @param1 is null OR Height = @param1