2015-02-06 6 views
7

Ich habe Code mit LINQ-Abfrage mit nHibernate und wenn es ausgeführt wird, wird ein PartialEvaluationExceptionExpression ausgelöst. Was genau bedeutet das und was kann ich dagegen tun?Was ist eine PartialEvaluationExceptionExpression und wie behebe ich sie?

SomeIqueryableNhibernateObject 
.Where(x=>... 
some expression 
&& !Model.date.HasValue ? true : (x.fooDate.Date == Model.date.Value.Date) 
&& some expresion 

Wo Modell ist:

public class Filter 
{ 
    DateTime? date; 
} 

Ausnahme durch den falschen Weg des ternären Operator verursacht wird:

x.fooDate.Date == Model.date.Value.Date 

Auch wenn ich ändern Sie es an:

x.fooDate != null && Model.date.HasValue && x.fooDate.Date == Model.date.Value.Date 

es löst immer noch die Ausnahme aus.

+0

Haben Sie in der Dokumentation zu "PartialEvaluationExceptionExpression" nachgeschaut, um zu sehen, was es darüber sagt, was diese Ausnahme bedeutet? – Servy

+0

Ich war überrascht, aber ich konnte keine klare Information über diese Ausnahme finden. Zum Beispiel dies: http://www.nudoq.org/#!/Packages/NHibernate/NHibernate/PartialEvaluationExceptionExpression - es bietet meiner Meinung nach keine nützlichen Informationen. – Landeeyo

+0

Das erste Google-Ergebnis für mich war das: http://www.nudoq.org/#!/Packages/Remotion.Linq/Remotion.Linq/PartialEvaluationExceptionExpression – Servy

Antwort

7

Sie führen Code aus, der den Wert eines null Objekts erhält, und so wird es geworfen. Wenn der Abfrageanbieter versucht, diese Abfrage in etwas zu übersetzen, das von der Datenbank ausgeführt werden kann, muss er Model.date.Value.Date in seinen Wert auflösen, damit der Wert in der Abfrage verwendet werden kann. Da es keinen Wert gibt, bricht der Code.

Die Lösung besteht natürlich darin, eine solche Prüfung nicht in die Abfrage selbst einzubinden. Bestimmen Sie, außerhalb des Kontexts der Abfrage, ob oder nicht, sollten Sie diese Überprüfung werden das Hinzufügen, und dann nur es wenn nötig:

var query = CreateInitialQuery(); 
if(Model.date.HasValue) 
    query = query.Where(x => x.fooDate.Date == Model.date.Value.Date); 

Hier ist die Abfrage-Provider immer nur einen Wert gegeben ist zu bewerten, wenn es tatsächlich ist ein zu bewertender Wert.

+1

Das Wichtigste für mich, das Sie geschrieben haben, ist der Teil über die Übersetzung LINQ-Ausdruck in SQL. Ich dachte zu viel "Imperativ", also war ich überrascht, warum der falsche Pfad ausgeführt wird, wenn die Bedingung wahr ist. Um ehrlich zu sein, habe ich das Problem vorher auf die gleiche Weise gelöst, indem ich es so extrahiert habe, wie du es geschrieben hast, aber ich wusste immer noch nicht, warum es nicht funktioniert. Jetzt verstehe ich die Ursache. Vielen Dank. – Landeeyo