Nibernate: CreateCriteria and Existe Cláusula
-
20-09-2019 - |
Pergunta
Como posso escrever o seguinte SQL usando CreateCriteria:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id)
Solução 3
Eu calculei como fazer isso usando a expressão de IsNotEmpty. Aqui está usando as extensões de Nibernate Lambda:
Session.CreateCriteria<FooBar>()
.Add(SqlExpression.IsNotEmpty<FooBar>(x => x.Bazes))
.List<FooBar>();
Outras dicas
Aqui está como você pode fazer isso:
var fooBars = Session.CreateCriteria<FooBar>()
.Add(Restrictions.IsNotEmpty("Bazs")).List<FooBar>();
... Supondo que exista uma propriedade de coleção (um para muitos) "bazas" no objeto Foobar.
Como alternativa, você pode usar critérios destacados como esse:
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>();
Tendo acabado de resolver um problema relacionado e eventualmente chegar a uma solução, pensei em compartilhar a resposta aqui:
Supondo que você queira a consulta de perguntas originais, com uma condição adicional no sub-quadro:
SELECT * FROM FooBar fb
WHERE EXISTS (SELECT FooBarId FROM Baz b WHERE b.FooBarId = fb.Id
AND Quantity = 5)
Supondo que você tenha uma referência na classe Baz ao pai, chamado, digamos foobarref [na classe de mapa fluente que você usaria o método references ()], você criaria a consulta da seguinte maneira:
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>();
Não estou 100% convencido sobre a codificação dura do pseudônimo "This", que é o alias que Nibernate atribui automaticamente à entidade raiz (tabela) na consulta, mas é a única maneira de fazer referência a chave do Tabela de consultas dos pais de dentro da sub-quadra.