【发布时间】:2010-12-16 04:30:07
【问题描述】:
我有一个这样的方法查询:
public IList<BusinessObject> GetBusinessObject(Guid? filterId)
{
using (var db = new L2SDataContext())
{
var result = from bo in db.BusinessObjects
where (filterId.HasValue)
? bo.Filter == filterId.value
: true
orderby bo.Name
select SqlModelConverters.ConvertBusinessObject(bo);
return result.ToList();
}
}
在运行时,这会抛出一个System.InvalidOperationException: Nullable object must have a value.
查看调试器,问题出在我的 Where Clause: Linq To SQL 尝试将整个事情转换为 SQL,所以即使 filterId 为 NULL,它仍然会尝试访问 filterId.value。
我认为/希望 C# 编译器/CLR 会将该 where 子句评估为代码块,并且只将两个分支之一发送到 Linq To SQL,但它不是这样工作的。
我的重构版本有效,但不是很优雅:
public IList<BusinessObject> GetBusinessObject(Guid? filterId)
{
using (var db = new L2SDataContext())
{
var temp = from bo in db.BusinessObjects select bo;
if(filterId.HasValue) temp = temp.Where(t => t.Filter == filterId.Value);
var result = from t in temp
orderby t.Name
select SqlModelConverters.ConvertBusinessObject(bo);
return result.ToList();
}
}
我知道延迟评估将确保只发送一个查询,但在其中包含该临时对象并没有那么好。
【问题讨论】:
标签: c# .net linq-to-sql