Избегайте «Обнуляемый объект должен иметь значение». в Линк-То-Скул - PullRequest
11 голосов
/ 15 декабря 2010

У меня есть запрос метода, подобный следующему:

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

Ответы [ 2 ]

16 голосов
/ 15 декабря 2010

Вы пробовали:

where filterId == null || t.Filter == filterId
1 голос
/ 15 декабря 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...