NHibernate - QueryOver-Abfragen
In diesem Kapitel werden QueryOver-Abfragen behandelt. Es handelt sich um eine neue Syntax, die eher LINQ ähnelt und die in der folgenden Abfrage gezeigte Methodenkettensyntax verwendet.
var customers = session.QueryOver<Customer>() .Where(x => x.FirstName == "Laverne");
Es ist immer noch ein Kriterium unter dem Deckmantel, aber jetzt sind unsere Abfragen stark typisiert.
Wie wir in der Kriterienabfrage gesehen haben, ist der Vorname nur eine undurchsichtige Zeichenfolge, jetzt verwenden wir tatsächlich eine x.FirstNameDaher wird der Vorname überarbeitet und umbenannt, der in der Abfrage der Kriterien für den Verbindungsstil mithilfe der Abfrage über geändert wird.
Wir können immer noch viele ähnliche Dinge tun, aber Sie können die Syntax des Abfrageverständnisses nicht mit Abfrage verwenden, Sie müssen die Syntax der Methodenkette verwenden und Sie können den Link und die Kriterien nicht mischen und abgleichen.
Für viele Abfragen ist die Abfrage über die API sehr nützlich und bietet eine viel einfachere Verständnis der Objektsyntax als die direkte Verwendung von Kriterien.
Schauen wir uns ein einfaches Beispiel an, in dem wir einen Kunden mit dem Vornamen Laverne mithilfe einer Abfrage abrufen.
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.QueryOver<Customer>()
.Where(x => x.FirstName == "Laverne");
foreach (var customer in customers.List()) {
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;
}
}
}
Wie Sie sehen können, ist es immer noch Kriterien unter dem Cover, aber es ist nur eine schönere Syntax.
Wenn der obige Code kompiliert und ausgeführt wird, wird die folgende Ausgabe angezeigt.
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...
Einer der Nachteile ist, dass wir das sagen wollen FirstName.StartsWith(“A”) wie im folgenden Programm gezeigt.
var customers = session.QueryOver<Customer>() .Where(x => x.FirstName.StartsWith("A"));
foreach (var customer in customers.List()) {
Console.WriteLine(customer);
}
tx.Commit();
Lassen Sie uns nun die Anwendung erneut ausführen und Sie werden sehen, dass dies kein LINQ-Anbieter ist, da er nicht weiß, was dies ist StartsWith Methode ist, so erhalten Sie eine RunTime exception.
Die Ausnahme besagt, dass der Methodenaufruf nicht erkannt wurde. Hier machen wir das Offensichtliche, aber es funktioniert nicht unbedingt.
Versuchen wir etwas anderes, wie Vorname ist gleich "A%", wie im folgenden Code gezeigt.
var customers = session.QueryOver<Customer>() .Where(x => x.FirstName == "A%");
foreach (var customer in customers.List()) {
Console.WriteLine(customer);
}
Lassen Sie uns dies noch einmal ausführen und Sie werden sehen, dass wir keine Ergebnisse zurückerhalten werden, wie unten gezeigt.
Press <ENTER> to exit...
Um zu verstehen, warum wir keine Ergebnisse erhalten, werfen wir einen Blick auf den NHibernate-Profiler.
Wie Sie sehen können, ist der Vorname gleich A%, was nicht der Fall ist. Ein% wird in SQL mit dem ähnlichen Operator verwendet. Jetzt müssen wir eine Einschränkung in der WHERE-Klausel erstellen, wie im folgenden Programm gezeigt.
var customers = session.QueryOver<Customer>()
.Where(Restrictions.On<Customer>(c => c.FirstName).IsLike("A%"));
foreach (var customer in customers.List()) {
Console.WriteLine(customer);
}
Lassen Sie uns Ihre Anwendung erneut ausführen und Sie werden sehen, dass alle Kunden mit dem Vornamen abgerufen werden, der mit A beginnt.
Alejandrin Will (4ea3aef6-6bce-11e1-b0b4-6cf049ee52be)
Points: 24
HasGoldStatus: False
MemberSince: 10/1/2011 12:00:00 AM (Utc)
CreditRating: VeryVeryGood
AverageRating: 0
Orders:
Order Id: 4ea3aef6-6bce-11e1-b0b5-6cf049ee52be
Austyn Nolan (4ea871b6-6bce-11e1-b110-6cf049ee52be)
Points: 67
HasGoldStatus: True
MemberSince: 12/29/2007 12:00:00 AM (Utc)
CreditRating: Neutral
AverageRating: 0
Orders:
Order Id: 4ea871b6-6bce-11e1-b111-6cf049ee52be
Antonia Murphy (4ea871b6-6bce-11e1-b121-6cf049ee52be)
Points: 72
HasGoldStatus: True
MemberSince: 6/15/2009 12:00:00 AM (Utc)
CreditRating: Terrible
AverageRating: 0
Orders:
Order Id: 4ea871b6-6bce-11e1-b122-6cf049ee52be
Order Id: 4ea871b6-6bce-11e1-b123-6cf049ee52be
Order Id: 4ea871b6-6bce-11e1-b124-6cf049ee52be
Order Id: 4ea871b6-6bce-11e1-b125-6cf049ee52be
Order Id: 4ea871b6-6bce-11e1-b126-6cf049ee52be
Order Id: 4ea871b6-6bce-11e1-b127-6cf049ee52be
Order Id: 4ea871b6-6bce-11e1-b128-6cf049ee52be
Order Id: 4ea871b6-6bce-11e1-b129-6cf049ee52be
Order Id: 4ea871b6-6bce-11e1-b12a-6cf049ee52be
Es funktioniert genauso wie zuvor, außer dass dieses neue verwendet wird QueryOverSyntax. Viele Entwickler finden, dass die LINQ-Syntax zugänglicher ist und oft die richtigen Dinge tut.
Wenn LINQ damit nicht umgehen kann, werden Sie sich HQL oder Kriterien ansehen, um festzustellen, ob dies besser geeignet ist.
Es gibt Ihnen nur eine andere Syntax, sodass Kriterien, sowohl die Erstellungskriterien als auch QueryOver, Ihnen nur einen weiteren Abfragemechanismus bieten, mit dem Sie Daten mit NHibernate aus der Datenbank abrufen können.