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