NHibernate - Laden / Holen
In diesem Kapitel werden wir beschreiben, wie die Funktionen Laden und Abrufen funktionieren und wie wir sie verwenden können. Dies sind zwei sehr ähnliche APIs, die von bereitgestellt werdenISession zum Laden eines Objekts per Primärschlüssel.
Get - Es wird das Objekt oder eine Null zurückgegeben.
Load - es wird das Objekt zurückgeben oder es wird ein werfen ObjectNotFoundException.
Warum haben wir diese zwei verschiedenen APIs?
Belastung
Dies liegt daran, dass Load Datenbank-Roundtrips viel effizienter optimieren kann.
Load gibt tatsächlich ein Proxy-Objekt zurück und muss nicht direkt auf die Datenbank zugreifen, wenn Sie diesen Load-Aufruf ausführen.
Wenn Sie auf diesen Proxy zugreifen, befindet sich das Objekt nicht in der Datenbank, sondern kann an diesem Punkt eine ObjectNotFoundException auslösen.
Bekommen
Umgekehrt mit Get wegen Einschränkungen der CLR oder Common Language Runtime und NHibernate muss sofort zur Datenbank gehen, prüfen, ob die Objekte vorhanden sind, und null zurückgeben, wenn sie nicht vorhanden sind.
Es hat nicht die Objektoption, diesen Abruf, diesen Roundtrip zur Datenbank zu einem späteren Zeitpunkt zu verzögern, da es kein Proxy-Objekt zurückgeben kann und dieses Proxy-Objekt gegen eine Null ausgetauscht hat, wenn der Benutzer tatsächlich darauf zugreift.
Schauen wir uns ein einfaches Beispiel an, in dem Sie sehen, wie diese tatsächlich verwendet werden und welchen Unterschied es zwischen Get und Load gibt. Wir werden mit denselben Domainklassen fortfahrenCustomers und Orders und ähnlich die gleichen Mapping-Dateien aus dem letzten Kapitel.
In diesem Beispiel verwenden wir zuerst Get, wie im folgenden Programm gezeigt.
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 id1 = Guid.Parse("4e97c816-6bce-11e1-b095-6cf049ee52be");
var id2 = Guid.Parse("AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE");
var customer1 = session.Get<Customer>(id1);
Console.WriteLine("Customer1 data");
Console.WriteLine(customer1);
var customer2 = session.Get<Customer>(id2);
Console.WriteLine("Customer2 data");
Console.WriteLine(customer2);
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, haben wir zwei GuidIDs, die erste ist eine gute ID, es ist die ID eines Kunden, von dem wir wissen, dass er sich in der Datenbank befindet. Während die zweite ID nicht in der Datenbank vorhanden ist. Diese beiden IDs werden als Parameter an übergebenGet() Methode und dann wird das Ergebnis auf der Konsole gedruckt.
Wenn der obige Code kompiliert und ausgeführt wird, wird die folgende Ausgabe angezeigt.
Customer1 data
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
Customer2 data
Press <ENTER> to exit...
Wie Sie sehen können, werden Customer1-Daten gedruckt, aber Customer2-Daten sind leer. Dies liegt daran, dass der Customer2-Datensatz nicht in der Datenbank verfügbar ist.
Wenn Sie Ihre Anwendung erneut ausführen, können wir vor der Festschreibungsanweisung einen Haltepunkt einfügen und dann beide Kunden im Überwachungsfenster betrachten.
Wie Sie sehen können, sind Customer1-Daten verfügbar, während Customer2 null und der Typ ist NHibernateDemo.Customer für beide.
Verwenden wir nun die Load-Methode anstelle von Get im selben Beispiel wie im folgenden Code.
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 id1 = Guid.Parse("4e97c816-6bce-11e1-b095-6cf049ee52be");
var id2 = Guid.Parse("AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE");
var customer1 = session.Load<Customer>(id1);
Console.WriteLine("Customer1 data");
Console.WriteLine(customer1);
var customer2 = session.Load<Customer>(id2);
Console.WriteLine("Customer2 data");
Console.WriteLine(customer2);
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;
}
}
}
Lassen Sie uns nun dieses Beispiel ausführen und Sie werden sehen, dass die folgende Ausnahme ausgelöst wird, wie im Screenshot gezeigt.
Wenn Sie sich nun das Überwachungsfenster ansehen, sehen Sie, dass der Typ für beide Objekte ein Kundenproxy ist. Die gleichen Daten für Customer1 werden auch im Konsolenfenster angezeigt.
Customer1 data
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
Customer2 data