Избегайте "Объект Nullable должен иметь значение". в 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();
    }
}

Во время выполнения это вызывает a System.InvalidOperationException: Nullable object must have a value.

Глядя на Debugger, проблема в том, что моя статья: Linq To SQL пытается преобразовать всю вещь в SQL, поэтому даже если filterId имеет значение NULL, он все равно попытается получить доступ к параметру filterId.value.

Я думал/надеялся, что компилятор С#/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 будет проверять, что только один запрос действительно отправлен, но наличие этого временного объекта там действительно не так уж велико.

Ответ 1

Вы пытались:

where filterId == null || t.Filter == filterId

Ответ 2

Ваше исправление точно верное. Вы эффективно пытаетесь создать запрос динамически, основываясь на своем вводе функции. Это хорошая идея опустить предложение where вместо того, чтобы поставлять WHERE TRUE в любом случае. Если бы я писал этот запрос, я бы пошел с вашей установленной версией.

Это не так красиво, как использование языковых ключевых слов, но по-прежнему это правильный подход к моему запросу.