NHibernate:CreateCriteria und Exists-Klausel
-
20-09-2019 - |
Frage
Wie kann ich schreiben Sie folgende SQL-Anweisungen mit CreateCriteria:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
Lösung 3
Ich arbeitete heraus, wie dies zu tun, um den IsNotEmpty Ausdruck. Hier wird mit NHibernate Lambda Erweiterungen:
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();
Andere Tipps
Hier ist, wie Sie es tun können:
var fooBars = Session.CreateCriteria<FooBar>()
.Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
... es unter der Annahme ist eine Sammlung Eigenschaft (one-to-many) "Bazs" im FooBar Objekt.
Alternativ können Sie wie die freistehenden Kriterien verwenden:
DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
.SetProjection(Projections.Property("baz.FooBarId"))
.Add(Restrictions.EqProperty("baz.FooBarId", "fooBar.Id"));
var fooBars = Session.CreateCriteria<FooBar>("fooBar")
.Add(Subqueries.Exists(dCriteria)).List<FooBar>();
Mit nur gelöst ein problem, und kamen schließlich auf eine Lösung, die ich dachte, ich würde teilen, hier die Antwort:
Angenommen, Sie möchten die original-Fragen-Abfrage, mit einer weiteren Bedingung, die auf der sub-query:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
AND Quantity = 5)
Vorausgesetzt, Sie haben ein Verweis auf die Baz-Klasse, um den Eltern, namens, sagen FooBarRef [ in Fließend Map-Klasse, die Sie verwenden würden die Referenzen () - Methode ], erstellen Sie die Abfrage wie folgt:
DetachedCriteria dCriteria = DetachedCriteria.For<Baz>("baz")
.SetProjection(Projections.Property("baz.FooBarId"))
.Add(Expression.EqProperty("this.FooBarId", "FooBarRef.Id"))
.Add(Expression.Eq("baz.Quantity", 5));
var fooBars = Session.CreateCriteria<FooBar>("fooBar")
.Add(Subqueries.Exists(dCriteria)).List<FooBar>();
Ich bin nicht 100% davon überzeugt, über die harte Codierung der alias "dies", das ist der alias NHibernate ordnet automatisch die root-Entität (Tabelle) in der Abfrage, aber es ist der einzige Weg, den ich gefunden habe, verweisen die Schlüssel des übergeordneten Abfrage-Tabelle in der sub-query.