NHibernate - Query sui criteri
In questo capitolo, tratteremo il meccanismo delle query sui criteri. IlNHibernate Query by Criteria API consente di creare una query manipolando oggetti criteri in fase di esecuzione.
Questo approccio consente di specificare i vincoli in modo dinamico senza manipolazioni dirette delle stringhe, ma non perde gran parte della flessibilità o della potenza di HQL.
D'altra parte, le query espresse come criteri sono spesso meno leggibili delle query espresse in HQL.
La sintassi dei criteri classici è un'API di query basata su oggetti come mostrato nel programma seguente.
var customers = session.CreateCriteria<Customer>().Add(Restrictions.Like("FirstName", "H%"));
Come puoi vedere, stiamo facendo una sessione per creare criteri sul cliente e ora stiamo aggiungendo un oggetto di restrizione a quella query.
Ciò è utile per le pagine di query in cui gli utenti possono selezionare determinate opzioni, ma non altre.
È più facile creare la query come un tipo di struttura ad albero come la struttura della query piuttosto che in HQL o LINQ, dove è possibile utilizzare AND o OR nella clausola WHERE.
È più semplice aggiungere ulteriori restrizioni utilizzando questi oggetti criteri.
Diamo un'occhiata a un semplice esempio in cui creeremo una query e avremo accesso all'API dei criteri tramite createCriteria e quindi aggiungi una restrizione in base alla quale il nome inizia con H.
using System;
using System.Data;
using System.Linq;
using System.Reflection;
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Linq;
namespace NHibernateDemo {
internal class Program {
private static void Main() {
var cfg = ConfigureNHibernate();
var sessionFactory = cfg.BuildSessionFactory();
using(var session = sessionFactory.OpenSession())
using(var tx = session.BeginTransaction()) {
var customers = session.CreateCriteria<Customer>()
.Add(Restrictions.Like("FirstName", "H%"));
foreach (var customer in customers.List<Customer>()) {
Console.WriteLine(customer);
}
tx.Commit();
}
Console.WriteLine("Press <ENTER> to exit...");
Console.ReadLine();
}
private static Configuration ConfigureNHibernate() {
NHibernateProfiler.Initialize();
var cfg = new Configuration();
cfg.DataBaseIntegration(x => {
x.ConnectionStringName = "default";
x.Driver<SqlClientDriver>();
x.Dialect<MsSql2008Dialect>();
x.IsolationLevel = IsolationLevel.RepeatableRead;
x.Timeout = 10;
x.BatchSize = 10;
});
cfg.SessionFactory().GenerateStatistics();
cfg.AddAssembly(Assembly.GetExecutingAssembly());
return cfg;
}
}
}
Quando il codice sopra è stato compilato ed eseguito, vedrai il seguente output.
Herman Crooks (4ead3480-6bce-11e1-b15c-6cf049ee52be)
Points: 74
HasGoldStatus: True
MemberSince: 12/3/2010 12:00:00 AM (Utc)
CreditRating: Neutral
AverageRating: 0
Orders:
Order Id: 4ead3480-6bce-11e1-b15d-6cf049ee52be
Order Id: 4ead3480-6bce-11e1-b15e-6cf049ee52be
Order Id: 4ead3480-6bce-11e1-b15f-6cf049ee52be
Order Id: 4ead3480-6bce-11e1-b160-6cf049ee52be
Order Id: 4ead3480-6bce-11e1-b161-6cf049ee52be
Order Id: 4ead3480-6bce-11e1-b162-6cf049ee52be
Order Id: 4ead3480-6bce-11e1-b163-6cf049ee52be
Hudson Bins (4ec03f80-6bce-11e1-b2b7-6cf049ee52be)
Points: 56
HasGoldStatus: False
MemberSince: 10/20/2008 12:00:00 AM (Utc)
CreditRating: Terrible
AverageRating: 0
Orders:
Order Id: 4ec03f80-6bce-11e1-b2b8-6cf049ee52be
Order Id: 4ec03f80-6bce-11e1-b2b9-6cf049ee52be
Order Id: 4ec03f80-6bce-11e1-b2ba-6cf049ee52be
Order Id: 4ec03f80-6bce-11e1-b2bb-6cf049ee52be
Order Id: 4ec03f80-6bce-11e1-b2bc-6cf049ee52be
Order Id: 4ec03f80-6bce-11e1-b2bd-6cf049ee52be
Order Id: 4ec03f80-6bce-11e1-b2be-6cf049ee52be
Order Id: 4ec03f80-6bce-11e1-b2bf-6cf049ee52be
Hettie Feest (4ec50240-6bce-11e1-b300-6cf049ee52be)
Points: 82
HasGoldStatus: False
MemberSince: 4/10/2009 12:00:00 AM (Utc)
CreditRating: Neutral
AverageRating: 0
Orders:
Order Id: 4ec50240-6bce-11e1-b301-6cf049ee52be
Order Id: 4ec50240-6bce-11e1-b302-6cf049ee52be
Order Id: 4ec50240-6bce-11e1-b303-6cf049ee52be
Press <ENTER> to exit…
Diamo un'occhiata a un altro semplice esempio in cui recupereremo il cliente il cui nome è uguale a "Laverne"
using System;
using System.Data;
using System.Linq;
using System.Reflection;
using HibernatingRhinos.Profiler.Appender.NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Linq;
namespace NHibernateDemo {
internal class Program {
private static void Main() {
var cfg = ConfigureNHibernate();
var sessionFactory = cfg.BuildSessionFactory();
using(var session = sessionFactory.OpenSession())
using(var tx = session.BeginTransaction()) {
var customers = session.CreateCriteria<Customer>()
.Add(Restrictions.Eq("FirstName", "Laverne")) .List<Customer>();
foreach (var customer in customers) {
Console.WriteLine(customer);
}
tx.Commit();
}
Console.WriteLine("Press <ENTER> to exit...");
Console.ReadLine();
}
private static Configuration ConfigureNHibernate() {
NHibernateProfiler.Initialize();
var cfg = new Configuration();
cfg.DataBaseIntegration(x => {
x.ConnectionStringName = "default";
x.Driver<SqlClientDriver>();
x.Dialect<MsSql2008Dialect>();
x.IsolationLevel = IsolationLevel.RepeatableRead;
x.Timeout = 10;
x.BatchSize = 10;
});
cfg.SessionFactory().GenerateStatistics();
cfg.AddAssembly(Assembly.GetExecutingAssembly());
return cfg;
}
}
}
Eseguiamo nuovamente questa applicazione e vedrai il seguente output.
Laverne Hegmann (4e97c816-6bce-11e1-b095-6cf049ee52be)
Points: 74
HasGoldStatus: True
MemberSince: 4/4/2009 12:00:00 AM (Utc)
CreditRating: Neutral
AverageRating: 0
Orders:
Order Id: 4ea14d96-6bce-11e1-b095-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b096-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b097-6cf049ee52be
Order Id: 4ea14d96-6bce-11e1-b098-6cf049ee52be
Press <ENTER> to exit...
Ora, uno dei principali svantaggi dell'API dei criteri sono queste stringhe opache nei nomi delle proprietà. Quindi, se il nome è stato refactoring per essere qualcos'altro, lo strumento di refactoring non raccoglierebbe necessariamente la stringa opaca.