避免"Nullable对象必须有值".在Linq-To-Sql中

Mic*_*tum 11 .net c# linq-to-sql

我有这样的方法查询:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在运行时,这会抛出一个 System.InvalidOperationException: Nullable object must have a value.

查看调试器,问题是我的Where子句: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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道Lazy-Evaluation将确保只发送一个查询,但在那里拥有那个临时对象并不是那么好.

Mr.*_* TA 16

你试过了吗:

where filterId == null || t.Filter == filterId
Run Code Online (Sandbox Code Playgroud)