Come posso scrivere il seguente SQL utilizzando createCriteria:NHibernate: createCriteria ed esiste clausola
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
Come posso scrivere il seguente SQL utilizzando createCriteria:NHibernate: createCriteria ed esiste clausola
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
ho trovato il modo di fare questo usando l'espressione IsNotEmpty. Qui si sta usando NHibernate Lambda estensioni:
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();
Ecco come si può fare:
var fooBars = Session.CreateCriteria<FooBar>()
.Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
... presumere che vi sia una proprietà della raccolta (uno-a-molti) "Baz" nell'oggetto FooBar.
In alternativa è possibile utilizzare criteri staccati così:
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>();
Avendo appena risolto un problema relativo e alla fine siamo arrivati ad una soluzione che ho pensato di condividere la risposta qui:
Supponendo che si desidera che la query di domande originali, con una condizione aggiuntiva sul sub-query:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
AND Quantity = 5)
Supponendo di avere un riferimento sulla classe Baz al genitore, chiamato, dicono FooBarRef [in Fluent Mappa classe che si userebbe i riferimenti() metodo], è creerebbe la query come segue:
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>();
Io non sono convinto al 100% circa difficile codifica del alias "questo", che è l'alias NHibernate assegna automaticamente al soggetto principale (tabella) nella query, ma è l'unico modo che ho trovato a fare riferimento alla chiave della tabella della query genitore dalla subquery.
In effetti ... e tu mi hai dato l'idea che si può fare in modo più semplice e senza le estensioni Lambda Nhibernate. Ho modificato la mia risposta per includere questa opzione. – tolism7