null vs default(decimal?) 设置为 null - 给出不同的结果
null vs default(decimal?) set to null - giving different results
Using: 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();
但是这条语句returns记录Id 1:
(from st in Stocks
where st.Height == null
select st.Id).ToList();
如果 scannedItemHeight 为空,我只想匹配高度也为空的值。
我只想return第一条记录,Id 1.
更新
我最终使用了:
st.Height == scannedItemHeight || (scannedItemHeight == null && st.Height == null)
我之前肯定见过一些奇怪的 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();
那是因为在第一种情况下数据库查询类似于
where Height = @param1 ...
而在第二种情况下会是
where Height is null
第一个查询将return没有结果,因为@param1 将为空并且没有行可以匹配这样的条件。
要点是,从 C# 的角度来看,这些查询是等效的,但从 sql 的角度来看,它们不是:您应该在 sql 中使用 IS NULL(或 IS NOT NULL)来检查空值.
如何解决取决于您在参数为空时要执行的操作。对于您的情况:使用 Jon Skeet 的回答。
如果有人想要忽略参数并且根本不按它进行过滤(很常见的情况,例如,当参数表示用户在某个字段中的输入时,当没有输入任何内容时 - 没有要过滤的内容),那么请执行以下操作:
where scannedItemHeight == null || st.Height == scannedItemHeight
这将在 sql 喜欢
where @param1 is null OR Height = @param1
Using: 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();
但是这条语句returns记录Id 1:
(from st in Stocks
where st.Height == null
select st.Id).ToList();
如果 scannedItemHeight 为空,我只想匹配高度也为空的值。
我只想return第一条记录,Id 1.
更新 我最终使用了:
st.Height == scannedItemHeight || (scannedItemHeight == null && st.Height == null)
我之前肯定见过一些奇怪的 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();
那是因为在第一种情况下数据库查询类似于
where Height = @param1 ...
而在第二种情况下会是
where Height is null
第一个查询将return没有结果,因为@param1 将为空并且没有行可以匹配这样的条件。
要点是,从 C# 的角度来看,这些查询是等效的,但从 sql 的角度来看,它们不是:您应该在 sql 中使用 IS NULL(或 IS NOT NULL)来检查空值.
如何解决取决于您在参数为空时要执行的操作。对于您的情况:使用 Jon Skeet 的回答。
如果有人想要忽略参数并且根本不按它进行过滤(很常见的情况,例如,当参数表示用户在某个字段中的输入时,当没有输入任何内容时 - 没有要过滤的内容),那么请执行以下操作:
where scannedItemHeight == null || st.Height == scannedItemHeight
这将在 sql 喜欢
where @param1 is null OR Height = @param1