Wie kann ich die folgende SQL verwenden CreateCriteria schreiben:NHibernate: CreateCriteria und Exists Klausel
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
Wie kann ich die folgende SQL verwenden CreateCriteria schreiben:NHibernate: CreateCriteria und Exists Klausel
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
Ich arbeitete heraus, wie dies die IsNotEmpty Ausdruck mit zu tun. Hier wird mit NHibernate Lambda Erweiterungen:
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();
Hier ist, wie Sie es tun können:
var fooBars = Session.CreateCriteria<FooBar>()
.Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
... vorausgesetzt, es gibt eine Sammlung Eigenschaft ist (eins-zu-viele) "Bazs" im FooBar-Objekt.
Alternativ können Sie frei stehende Kriterien verwenden wie folgt aus:
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>();
Nachdem nur ein verwandtes Problem gelöst und kam schließlich an einer Lösung, die ich dachte, dass ich hier die Antwort teilen würde:
Angenommen Sie haben die ursprünglichen Fragen Abfrage mögen, mit eine zusätzliche Bedingung auf der Unterabfrage:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
AND Quantity = 5)
Angenommen, Sie einen Verweis auf der Baz-Klasse an die Eltern haben, genannt, sagen FooBarRef [in Fluent Map-Klasse Sie die Referenzen verwenden würde() -Methode], Sie würde die Abfrage wie folgt erstellen:
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% überzeugt, über harte Codierung des alias „dies“, die die Alias NHibernate ordnet automatisch an die Root-Entität (Tabelle) in der Abfrage, aber es ist der einzige Weg, ich habe gefunden, um den Schlüssel der Tabelle der übergeordneten Abfrage innerhalb der Unterabfrage zu referenzieren.
In der Tat ... und du hast mir die Idee gegeben, dass es einfacher und ohne die Nhibernate Lambda-Erweiterungen gemacht werden kann. Ich habe meine Antwort bearbeitet, um diese Option einzuschließen. – tolism7