Upload
mauro-matias-pies
View
145
Download
5
Embed Size (px)
Citation preview
Capí tulo 15. consultas crité rios NHibernate possui uma interface intuitiva, API de consulta extensível
critérios.
15.1. Criando uma instância ICriteria O NHibernate.ICriteria interface representa uma consulta contra uma classe
particular persistente. O ISession é uma fábrica para instâncias ICriteria.
ICriteria crit = sess.CreateCriteria(typeof(Cat));
crit.SetMaxResults(50);
List cats = crit.List();
15.2. Estreitando o conjunto de resultados Um critério de consulta individual é uma instância da
NHibernate.Expression.ICriterion interface. O
NHibernate.Expression.Expression classe define métodos de fábrica para a
obtenção de built-in certos tipos ICriterion.
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "Fritz%") )
.Add( Expression.Between("Weight", minWeight, maxWeight) )
.List();
Expressões podem ser agrupadas de maneira lógica.
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "Fritz%") )
.Add( Expression.Or(
Expression.Eq( "Age", 0 ),
Expression.IsNull("Age")
) )
.List();
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.In( "Name", new String[] { "Fritz", "Izi", "Pk" } ) )
.Add( Expression.Disjunction()
.Add( Expression.IsNull("Age") )
.Add( Expression.Eq("Age", 0 ) )
.Add( Expression.Eq("Age", 1 ) )
.Add( Expression.Eq("Age", 2 ) )
) )
.List();
Há um leque bastante de tipos built-in critério (subclasses de expressão),
mas que é especialmente útil permite que você especifique o SQL
diretamente.
// Create a string parameter for the SqlString below
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Sql("lower({alias}.Name) like lower(?)", "Fritz%",
NHibernateUtil.String )
.List();
O espaço reservado {alias} com ser substituído pelo apelido de linha da
entidade consultada.
15.3. Ordenar os resultados Você pode ordenar os resultados usando NHibernate.Expression.Order.
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "F%")
.AddOrder( Order.Asc("Name") )
.AddOrder( Order.Desc("Age") )
.SetMaxResults(50)
.List();
15.4. associações Você pode facilmente especificar restrições sobre entidades relacionadas ao
navegar associações usando CreateCriteria ().
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "F%")
.CreateCriteria("Kittens")
.Add( Expression.Like("Name", "F%") )
.List();
note que o CreateCriteria segundo () retorna uma nova instância de
ICriteria, que se refere aos elementos da coleção gatinhos.
A forma, a seguir alternativa é útil em certas circunstâncias.
IList cats = sess.CreateCriteria(typeof(Cat))
.CreateAlias("Kittens", "kt")
.CreateAlias("Mate", "mt")
.Add( Expression.EqProperty("kt.Name", "mt.Name") )
.List();
(CreateAlias () não cria uma nova instância ICriteria.)
Note-se que as coleções gatinhos detidos pelas instâncias de Cat devolvidos
pelas duas consultas não são pré-filtrada pelos critérios! Se você deseja
recuperar apenas os gatinhos que correspondem aos critérios, você deve
usar SetResultTransformer (Transformers.AliasToEntityMap).
IList cats = sess.CreateCriteria(typeof(Cat))
.CreateCriteria("Kittens", "kt")
.Add( Expression.Eq("Name", "F%") )
.SetResultTransformer(Transformers.AliasToEntityMap)
.List();
foreach ( IDictionary map in cats )
{
Cat cat = (Cat) map[CriteriaUtil.RootAlias];
Cat kitten = (Cat) map["kt"];
15.5. Buscar associação dinâmica
Você pode especificar associação busca semântica em tempo de execução
usando setFetchMode ().
IList cats = sess.CreateCriteria(typeof(Cat))
.Add( Expression.Like("Name", "Fritz%") )
.SetFetchMode("Mate", FetchMode.Eager)
.SetFetchMode("Kittens", FetchMode.Eager)
.List();
Esta consulta vai buscar tanto Mate e Gatinhos por junção externa. Veja
Seção 19.1, "Buscando estratégias" para mais informações.
15.6. consultas de exemplo
O NHibernate.Expression.Example classe permite que você construir um
critério de consulta a partir de uma determinada instância.
Cat cat = new Cat();
cat.Sex = 'F';
cat.Color = Color.Black;
List results = session.CreateCriteria(typeof(Cat))
.Add( Example.Create(cat) )
.List();
Versão propriedades, identificadores e associações são ignorados. Por
padrão, nulo Propriedades com valores e propriedades que retornam uma
cadeia vazia da chamada para ToString () são excluídos.
Você pode ajustar como o exemplo é aplicado.
Example example = Example.Create(cat)
.ExcludeZeroes() //exclude null- or zero-valued properties
.ExcludeProperty("Color") //exclude the property named "color"
.IgnoreCase() //perform case insensitive string comparisons
.EnableLike(); //use like for string comparisons
IList results = session.CreateCriteria(typeof(Cat))
.Add(example)
.List();
Você ainda pode usar exemplos para colocar critérios sobre os objetos
associados.
IList results = session.CreateCriteria(typeof(Cat))
.Add( Example.Create(cat) )
.CreateCriteria("Mate")
.Add( Example.Create( cat.Mate ) )
.List();
15.7. Projeções de agregação e agrupamento
Os NHibernate.Expression.Projections classe é uma fábrica para instâncias
IProjection. Nós aplicamos uma projeção para uma consulta chamando
SetProjection ().
IList results = session.CreateCriteria(typeof(Cat))
.SetProjection( Projections.RowCount() )
.Add( Expression.Eq("Color", Color.BLACK) )
.List();
List results = session.CreateCriteria(typeof(Cat))
.SetProjection( Projections.ProjectionList()
.Add( Projections.RowCount() )
.Add( Projections.Avg("Weight") )
.Add( Projections.Max("Weight") )
.Add( Projections.GroupProperty("Color") )
)
.List();
Não existe um "grupo de" explícito necessário uma consulta critérios. Certos
tipos de projeção são definidos para ser projeções de agrupamento, que
também aparecem no grupo SQL por cláusula.
Um alias pode, opcionalmente, ser atribuído a uma de projecção, de modo
que o valor previsto pode ser referido em restrições ou ordenações. Aqui
estão duas maneiras diferentes de fazer isso:
IList results = session.CreateCriteria(typeof(Cat))
.SetProjection( Projections.Alias( Projections.GroupProperty("Color"), "colr" ) )
.AddOrder( Order.Asc("colr") )
.List();
IList results = session.CreateCriteria(typeof(Cat))
.SetProjection( Projections.GroupProperty("Color").As("colr") )
.AddOrder( Order.Asc("colr") )
.List();
Os Alias () e como () métodos simplesmente enrolar um exemplo de
projeção no outro, alias exemplo, de IProjection. Como um atalho, você
pode atribuir um alias quando você adicionar a projeção de uma lista de
projeção:
IList results = session.CreateCriteria(typeof(Cat))
.SetProjection( Projections.ProjectionList()
.Add( Projections.RowCount(), "catCountByColor" )
.Add( Projections.Avg("Weight"), "avgWeight" )
.Add( Projections.Max("Weight"), "maxWeight" )
.Add( Projections.GroupProperty("Color"), "color" )
)
.AddOrder( Order.Desc("catCountByColor") )
.AddOrder( Order.Desc("avgWeight") )
.List();
IList results = session.CreateCriteria(typeof(DomesticCat), "cat")
.CreateAlias("kittens", "kit")
.SetProjection( Projections.ProjectionList()
.Add( Projections.Property("cat.Name"), "catName" )
.Add( Projections.Property("kit.Name"), "kitName" )
)
.AddOrder( Order.Asc("catName") )
.AddOrder( Order.Asc("kitName") )
.List();
15.8. Moradia consultas e subconsultas
A classe DetachedCriteria permite que você crie uma consulta fora do
escopo de uma sessão, e depois executá-lo usando algum ISession
arbitrária.
DetachedCriteria query = DetachedCriteria.For(typeof(Cat))
.Add( Expression.Eq("sex", 'F') );
ISession session = ....;
ITransaction txn = session.BeginTransaction();
IList results = query.GetExecutableCriteria(session).SetMaxResults(100).List();
txn.Commit();
session.Close();
Um DetachedCriteria pode também ser usado para expressar uma
subconsulta. ICriterion casos envolvendo subconsultas podem ser obtidas
através subconsultas.
DetachedCriteria avgWeight = DetachedCriteria.For(typeof(Cat))
.SetProjection( Projections.Avg("Weight") );
session.CreateCriteria(typeof(Cat))
.Add( Subqueries.Gt("Weight", avgWeight) )
.List();
DetachedCriteria weights = DetachedCriteria.For(typeof(Cat))
.SetProjection( Projections.Property("Weight") );
session.CreateCriteria(typeof(Cat))
.add( Subqueries.GeAll("Weight", weights) )
.list();
Mesmo subqueries correlacionadas são possíveis:
DetachedCriteria avgWeightForSex = DetachedCriteria.For(typeof(Cat), "cat2")
.SetProjection( Projections.Avg("Weight") )
.Add( Expression.EqProperty("cat2.Sex", "cat.Sex") );
session.CreateCriteria(typeof(Cat), "cat")
.Add( Subqueries.Gt("weight", avgWeightForSex) )
.List();