Mam zapytanie metoda tak:Unikaj "obiektu Nullable musi mieć wartość." w LINQ-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();
}
}
W czasie wykonywania tego rzuca System.InvalidOperationException: Nullable object must have a value.
Patrząc na Debugger, problem jest moja Gdzie klauzuli: LINQ Aby próbach SQL aby przekonwertować całą zawartość na SQL, więc nawet jeśli filterId ma wartość NULL, nadal będzie próbował uzyskać dostęp do właściwości filterId.value.
Myślałem/mam nadzieję, że kompilator C/CLR oceni, że klauzula where jest blokiem kodu i wysyła tylko jedną z dwóch gałęzi Linq To SQL, ale tak nie działa.
Moja refactored wersja działa, ale nie jest bardzo elegancki:
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();
}
}
wiem, że Lazy-ocena będzie upewnić się, że tylko jeden jest naprawdę wysłał zapytanie, ale o ten obiekt w temp nie jest to, że świetnie, naprawdę.
Oh wow, który działa doskonale! Oszczędza mi to przed używaniem nieco nieczytelnego operatora trzeciorzędowego i rozwiązuje rzeczywisty wyjątek spowodowany niepotrzebnym dostępem do właściwości filterId.Value, a nie tylko filtrem filterId. –