NHibernate - Carica / Ottieni
In questo capitolo tratteremo come funzionano le funzionalità Carica e Ottieni e come possiamo usarle. Queste sono due API molto simili fornite daISession per caricare un oggetto tramite chiave primaria.
Get - restituirà l'oggetto o un null.
Load - restituirà l'oggetto o lancerà un file ObjectNotFoundException.
Ora, perché abbiamo queste due API diverse?
Caricare
È perché Load può ottimizzare i round trip del database in modo molto più efficiente.
Load restituisce effettivamente un oggetto proxy e non ha bisogno di accedere al database proprio quando si emette quella chiamata Load.
Quando accedi a quel proxy, l'oggetto non si trova nel database, può generare un'eccezione ObjectNotFoundException a quel punto.
Ottenere
Al contrario, con Get a causa delle limitazioni di CLR o Common Language Runtime e NHibernate deve andare immediatamente al database, controllare se gli oggetti sono presenti e restituire null, se non è presente.
Non ha l'opzione oggetto di ritardare quel recupero, quel viaggio di andata e ritorno al database in un momento successivo perché non può restituire un oggetto proxy e che ha sostituito quell'oggetto proxy con un null, quando l'utente vi accede effettivamente.
Diamo un'occhiata a un semplice esempio in cui vedrai come vengono effettivamente utilizzati e la differenza tra Get e Load. Continueremo con le stesse classi di dominioCustomers e Orders e allo stesso modo gli stessi file di mappatura dell'ultimo capitolo.
In questo esempio, useremo prima il Get come mostrato nel seguente programma.
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;
}
}
}
Come puoi vedere, ne abbiamo due GuidID, il primo è un buon ID, è l'ID di un cliente che sappiamo si trova nel database. Mentre il secondo ID non è presente nel database. Entrambi questi ID vengono passati come parametro aGet() metodo e quindi il risultato viene stampato sulla console.
Quando il codice sopra è stato compilato ed eseguito, vedrai il seguente output.
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...
Come puoi vedere, i dati Customer1 vengono stampati ma i dati Customer2 sono vuoti, perché il record Customer2 non è disponibile nel database.
Quando si esegue nuovamente l'applicazione, è possibile inserire un punto di interruzione prima dell'istruzione commit e quindi esaminare entrambi i clienti nella finestra di controllo.
Come puoi vedere che i dati di Customer1 sono disponibili, mentre Customer2 è nullo e il tipo è NHibernateDemo.Customer per entrambi.
Ora usiamo il metodo Load invece di Get nello stesso esempio mostrato nel codice seguente.
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;
}
}
}
Ora eseguiamo questo esempio e vedrai che viene generata la seguente eccezione come mostrato nello screenshot.
Ora, se guardi la finestra Watch, vedrai che il tipo è proxy del cliente per entrambi gli oggetti. Inoltre, nella finestra della console vengono visualizzati gli stessi dati per Customer1.
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