Wie kann ich „nicht in“ mit Lambda-Ausdrücke ausdrücken?
-
30-09-2019 - |
Frage
Ich versuche, eine not in
-Klausel mit dem NHibernate Criteria API NHLambdaExtensions zu erstellen. Das Lesen der Dokumentation konnte ich die in
Klausel, indem Sie
.Add(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }))
Allerdings, wenn ich es um wickeln SqlExpression.Not
ich den Fehler
Error 5 The best overloaded method match for 'NHibernate.LambdaExtensions.SqlExpression.Not<oms_dal.Models.Zone>(System.Linq.Expressions.Expression<System.Func<oms_dal.Models.Zone,bool>>)' has some invalid arguments
Error 6 Argument '1': cannot convert from 'NHibernate.Criterion.ICriterion' to 'System.Linq.Expressions.Expression<System.Func<oms_dal.Models.Zone,bool>>'
Ich verwende dieses Stück Code
.Add(SqlExpression.Not<Zone>(SqlExpression.In<Zone>(x => zoneAlias.ZoneId, new int[] { 1008, 1010 })))
Wie kann ich das erreichen? Mit Hilfe der regulären Criteria API konnte ich diese
tun.Add(Restrictions.Not(Restrictions.In("z.ZoneId", new[] { 1008, 1010 })))
Lösung
Haben Sie mit Kriterium nicht direkt gearbeitet (ich benutze Linq2NH im Allgemeinen), aber es sieht aus wie nicht nur ein boolean Lambda will, so dass Sie es nicht ein weiteres Kriterium geben kann. Das kann funktionieren, obwohl ich NH Probleme gesehen habe habe mit Array-Mitgliedern in lambdas:
.Add(SqlExpression.Not<Zone>(z=>new[]{1008,1010}.Contains(z.ZoneId))
EDIT: Mist. Was ist hier los ist, dass der Rahmen des Lambda nicht tatsächlich verwendet, so dass während dieses compiliert, der Rahmen nie nennt es tatsächlich in dem Prozess die Abfrage von ausgeführt wird. Es wird stattdessen die Prüfung reflektiv die MSIL Ihrer Delegierten, Reverse-Engineering Ihre Lambda-Ausdruck, und dass für den SQL-Befehl in eine Zeichenfolge zu konvertieren. Das heißt, natürlich, ein ziemlich komplexer Prozess, dass die Designer von zu vereinfachen versuchen, Sie Hinweise geben, was Sie tun (in diesem Fall die Art von SqlExpression Sie deklariert) und auf der Suche nach Mustern, den Prozess zu identifizieren. aber auch die Hinweise in diesem Fall, da der Rahmen keine Ahnung hat, was Sie versuchen zu tun.
Wenn der Übersetzer hinter der Bewertung nicht () Klauseln nicht den Zweck der Logik Schleifen oder Methodenaufrufe prophezeien kann, können Sie auch mit geklebt werden
.Add(SqlExpression.Not<Zone>(z=>z.ZoneId == 1008
|| z.ZoneId == 1010))
Wer weiß, ich habe Ausdrücke einkochen auf diese Weise für Linq2NHibernate richtig zu arbeiten.
Andere Tipps
Mit der alten Welt mit den lambdas scheint zu funktionieren:
.Add(Expression.Not(SqlExpression.In<Zone>(z => zoneAlias.ZoneId, new int[] { 1008, 1010 }));