NHibernate: createCriteria et d 'une clause
-
20-09-2019 - |
Question
Comment puis-je écrire le SQL à l'aide createCriteria:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
La solution 3
Je travaillais comment faire cela en utilisant l'expression IsNotEmpty. Ici, il utilise les extensions NHibernate Lambda:
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();
Autres conseils
Voici comment vous pouvez le faire:
var fooBars = Session.CreateCriteria<FooBar>()
.Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
... en supposant qu'il existe une propriété de collection (un à plusieurs) "Bazs" dans l'objet FooBar.
vous pouvez également utiliser des critères comme détachés:
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>();
Après avoir résolu simplement un problème lié et est finalement arrivé à une solution que je pensais que je partagerais la réponse ici:
En supposant que vous voulez la requête des questions d'origine, avec une condition supplémentaire sur la sous-requête:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
AND Quantity = 5)
En supposant que vous avez une référence sur la classe Baz au parent, appelé, dit FooBarRef [en classe Fluent Carte vous utiliseriez la méthode Références ()], vous créez la requête comme suit:
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>();
Je ne suis pas convaincu à 100% sur le codage dur de l'alias « ce » qui est l'alias NHibernate attribue automatiquement à l'entité racine (tableau) dans la requête, mais c'est la seule façon que je l'ai trouvé pour faire référence à la clé de la table de la requête parent à l'intérieur de la sous-requête.