C# 布尔运算的LINQ到SQL求值顺序
我有以下代码,当我向C# 布尔运算的LINQ到SQL求值顺序,c#,sql,linq,linq-to-sql,C#,Sql,Linq,Linq To Sql,我有以下代码,当我向PerformQuery方法提供null参数时,它会生成null引用异常 public class MyObject { public Guid Guid { get; private set; } } public class TableObject { // This is a Guid stored as a string public string Hash { get; set; } } public DataContext context;
PerformQuery
方法提供null参数时,它会生成null引用异常
public class MyObject
{
public Guid Guid { get; private set; }
}
public class TableObject
{
// This is a Guid stored as a string
public string Hash { get; set; }
}
public DataContext context;
public TableObject PerformQuery(MyObject obj)
{
return context.TableObjects.FirstOrDefault(tableObject =>
obj != null &&
// Why is this side of the condition being evaluated if obj is null?
string.Equals(obj.Guid.ToString(), tableObject.Hash));
}
我确信TableObject
不是空的。怎么可能呢?它的属性Hash
不可为null,因此也不应为null(尽管我已经检查了这两个属性是否为null,但没有任何改进)
在执行查询之前,我通过计算正在搜索的Guid字符串自己解决了这个问题,但我很好奇为什么LINQ即使
obj
为空,也会继续计算条件。这是因为LINQ-to-SQL优化,布尔值的计算顺序与传统的if-else
语句不同吗?您应该在输入LINQ-to-SQL查询之前计算本地对象。数据库无法知道对象是否为null
public TableObject PerformQuery(MyObject obj) {
if (obj == null) {return null;}
// also pull this out of the LINQ logic.
string objGuid = obj.Guid.ToString();
return context.TableObjects.FirstOrDefault(tableObject =>
string.Equals(objGuid, tableObject.Hash));
}
这是因为LINQtoSQL尝试将整个表达式转换为sql。因此,在转换过程中会出现空对象引用。您可以知道,因为甚至没有向数据库发送SQL 解决方案是在编写查询之前评估
obj.Guid
(如@ps2goat的回答,但原因略有不同)。谢谢,我一直在寻找原因,而不是我已有的解决方案。