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