NHibernate - Cargar / Obtener

En este capítulo, cubriremos cómo funcionan las funciones Load y Get y cómo podemos usarlas. Estas son dos API muy similares proporcionadas porISession para cargar un objeto por clave primaria.

  • Get - devolverá el objeto o un nulo.

  • Load - devolverá el objeto o lanzará un ObjectNotFoundException.

Ahora bien, ¿por qué tenemos estas dos API diferentes?

Carga

  • Es porque Load puede optimizar los viajes de ida y vuelta de la base de datos de manera mucho más eficiente.

  • Load realmente devuelve un objeto proxy y no necesita acceder a la base de datos justo cuando emite esa llamada Load.

  • Cuando accede a ese proxy, el objeto no está en la base de datos, puede lanzar una ObjectNotFoundException en ese punto.

Obtener

  • Por el contrario, con Get debido a las limitaciones de CLR o Common Language Runtime y NHibernate debe ir a la base de datos inmediatamente, verificar si los objetos están allí y devolver nulo, si no está presente.

  • No tiene la opción de objeto de retrasar esa recuperación, ese viaje de ida y vuelta a la base de datos a un momento posterior porque no puede devolver un objeto proxy y eso cambió ese objeto proxy por un valor nulo, cuando el usuario realmente accede a él.

Echemos un vistazo a un ejemplo simple en el que verá cómo se utilizan realmente y la diferencia entre Get y Load. Continuaremos con las mismas clases de dominioCustomers y Orders e igualmente los mismos archivos de mapeo del último capítulo.

En este ejemplo, primero usaremos Get como se muestra en el siguiente programa.

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; 
      } 
   } 
}

Como puedes ver que tenemos dos GuidIdentificación, la primera es una buena identificación, es la identificación de un cliente que sabemos que está en la base de datos. Mientras que el segundo ID no está presente en la base de datos. Ambos ID se pasan como parámetro aGet() método y luego el resultado se imprime en la consola.

Cuando se compile y ejecute el código anterior, verá el siguiente resultado.

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...

Como puede ver, los datos de Customer1 se imprimen pero los datos de Customer2 están vacíos, esto se debe a que el registro de Customer2 no está disponible en la base de datos.

Cuando vuelva a ejecutar su aplicación, podemos insertar un punto de interrupción antes de la declaración de confirmación y luego observemos a ambos clientes en la ventana Inspección.

Como puede ver, los datos de Customer1 están disponibles, mientras que Customer2 es nulo y el tipo es NHibernateDemo.Customer para ambos.

Ahora usemos el método Load en lugar de Get en el mismo ejemplo que se muestra en el siguiente código.

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; 
      } 
   } 
}

Ahora ejecutemos este ejemplo y verá que se lanza la siguiente excepción como se ve en la captura de pantalla.

Ahora, si observa la ventana Inspección, verá que el tipo es proxy de cliente para ambos objetos. Y también verá los mismos datos para Customer1 en la ventana de la consola.

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