簡體   English   中英

在Linq-To-Sql中避免“Nullable對象必須有值。”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM