Domanda

Come posso scrivere il seguente SQL utilizzando CreateCriteria:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
È stato utile?

Soluzione 3

Ho lavorato come fare ciò utilizzando l'espressione IsNotEmpty. Qui si sta usando estensioni NHibernate Lambda:

Session.CreateCriteria<FooBar>()
    .Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
    .List<FooBar>();

Altri suggerimenti

Ecco come si può fare:

var fooBars = Session.CreateCriteria<FooBar>()
        .Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();

... c'è assumendo è una proprietà della raccolta (uno-a-molti) "Bazs" 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 correlato e alla fine arrivato a una soluzione, ho pensato di condividere la risposta qui:

Supponendo che tu voglia la query delle domande originali, con una condizione aggiuntiva nella sottoquery:

SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
              AND Quantity = 5)

Supponendo che tu abbia un riferimento sulla classe Baz al genitore, chiamato, diciamo FooBarRef [nella classe Fluent Map utilizzeresti il ​​metodo References() ], creerai 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>();

Non sono convinto al 100% dell'hard coding dell'alias "this", che è l'alias che NHibernate assegna automaticamente all'entità root (tabella) nella query, ma è l'unico modo che ho trovato per fare riferimento alla chiave del tabella della query principale dall'interno della sottoquery.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top