![](/img/trans.png)
[英]linq .Value Nullable Object must have a value. How to skip?
[英]Avoid “Nullable object must have a value.” in 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();
}
}
在運行時,這會拋出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();
}
}
我知道Lazy-Evaluation將確保只發送一個查詢,但在那里擁有那個臨時對象並不是那么好。
你試過了嗎:
where filterId == null || t.Filter == filterId
你的修復完全正確。 您正在有效地嘗試根據您的函數輸入動態構建查詢。 省略where子句而不是提供WHERE TRUE
是個好主意。 如果我正在編寫此查詢,我會自己使用您的固定版本。
它不像使用語言關鍵字那么漂亮,但在我看來,它仍然是處理查詢的正確方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.