NHibernate - Carregar / Obter
Neste capítulo, abordaremos como os recursos Carregar e Obter estão funcionando e como podemos usá-los. Estas são duas APIs muito semelhantes fornecidas porISession para carregar um objeto por chave primária.
Get - ele retornará o objeto ou um nulo.
Load - retornará o objeto ou lançará um ObjectNotFoundException.
Agora, por que temos essas duas APIs diferentes?
Carga
É porque o Load pode otimizar as viagens de ida e volta do banco de dados com muito mais eficiência.
O carregamento, na verdade, retorna um objeto proxy e não precisa acessar o banco de dados direito ao emitir a chamada de carregamento.
Quando você acessa esse proxy, o objeto não está no banco de dados, ele pode lançar uma ObjectNotFoundException naquele ponto.
Pegue
Por outro lado, com Get devido às limitações do CLR ou Common Language Runtime e o NHibernate deve ir ao banco de dados imediatamente, verificar se os objetos estão lá e retornar nulo, se não estiver presente.
Ele não tem a opção do objeto de atrasar essa busca, aquela viagem de ida e volta ao banco de dados para um momento posterior, porque não pode retornar um objeto proxy e que trocou esse objeto proxy por um nulo, quando o usuário realmente o acessa.
Vamos dar uma olhada em um exemplo simples no qual você verá como eles são realmente usados e a diferença entre Get e Load. Continuaremos com as mesmas classes de domínioCustomers e Orders e da mesma forma os mesmos arquivos de mapeamento do capítulo anterior.
Neste exemplo, primeiro usaremos Get conforme mostrado no programa a seguir.
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 você pode ver, temos dois GuidIDs, o primeiro é um bom ID, é o ID de um cliente que sabemos que está no banco de dados. Enquanto o segundo ID não está presente no banco de dados. Ambos os IDs são passados como um parâmetro paraGet() método e então o resultado é impresso no console.
Quando o código acima for compilado e executado, você verá a seguinte saída.
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 você pode ver, os dados do Cliente1 são impressos, mas os dados do Cliente2 estão vazios, isso porque o registro do Cliente2 não está disponível no banco de dados.
Quando você executa seu aplicativo novamente, podemos inserir um ponto de interrupção antes da instrução de confirmação e, em seguida, vamos examinar os dois clientes na janela Watch.
Como você pode ver que os dados do Cliente1 estão disponíveis, enquanto o Cliente2 é nulo e o tipo é NHibernateDemo.Customer para ambos.
Agora vamos usar o método Load em vez de Get no mesmo exemplo mostrado no código a seguir.
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;
}
}
}
Agora, vamos executar este exemplo e você verá que a seguinte exceção é lançada conforme visto na imagem.
Agora, se você olhar para a janela Watch, verá que o tipo é proxy do cliente para ambos os objetos. E você também vê os mesmos dados para Customer1 na janela do console.
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