O NHibernate é, indiscutivelmente, um poderoso framework ORM para .NET. No entanto, em muitas ocasiões, ele é criticado por problemas de desempenho. Essas críticas podem ser, em grande parte, atribuídas ao uso inadequado ou à subutilização de suas funcionalidades.
Existem diversas formas de recuperar as entidades do banco de dados, mas as principais maneiras são através dos métodos Get
e Load
. Os dois métodos são utilizados para para recuperar entidades por meio de seus identificadores, mas eles têm diferenças fundamentais que podem afetar o desempenho da aplicação, especialmente quando usados de forma inadequada.
Neste artigo, exploraremos a diferença entre esses métodos e como otimizar o desempenho utilizando o método Load
de forma correta.
Método Get
:
O método Get
é uma maneira simples e direta de recuperar uma entidade pelo seu identificador. Ele consulta o banco de dados imediatamente e retorna o objeto correspondente ou nulo (caso o objeto não seja encontrado). A chamada ao Get
resulta em uma consulta SQL para recuperar os dados da entidade específica e, em seguida, o NHibernate materializa o objeto C# correspondente.
Exemplo:
using NHibernate;
// ...
using (ISession session = sessionFactory.OpenSession())
{
return session.Get<TEntity>(id);
}
Método Load
:
O método Load
, por outro lado, não executa a consulta SQL imediatamente. Em vez disso, ele retorna uma instância proxy da entidade, onde as propriedades são inicializadas como "preguiçosas" (lazy). A consulta SQL real para buscar os dados no banco de dados é adiada até que alguma propriedade do objeto proxy seja acessada. Isso pode ser uma vantagem significativa em termos de desempenho, pois evita uma consulta desnecessária quando você só precisa da chave da entidade.
Exemplo:
using NHibernate;
// ...
using (ISession session = sessionFactory.OpenSession())
{
return session.Load<TEntity>(id);
}
Diferença chave entre Get
e Load
:
- O método
Get
retorna o objeto real do banco de dados imediatamente e gera uma consulta SQL imediata e retorna null quando a chave não existe no banco de dados. - O método
Load
retorna um proxy de entidade e adia a consulta SQL até que uma propriedade seja acessada no objeto e retorna uma exception no caso de não encontrar a chave no banco de dados.
Como aumentar a performance utilizando o método Load
de forma correta:
O uso adequado do método Load
pode trazer melhorias significativas de desempenho para a aplicação, mas é essencial saber quando e como utilizá-lo:
Cuidado com o uso em contexto desconectado: O método
Load
requer que a sessão do NHibernate esteja ativa para funcionar corretamente, o que pode ser um problema em contextos desconectados, como ambientes web. Se o objeto proxy for acessado após a sessão ter sido encerrada, ocorrerá uma exceção do tipoLazyInitializationException
.Evite o acesso a propriedades que requerem consulta ao banco de dados: Se você usar o método
Load
, evite acessar propriedades que tenham relacionamentos de muitos-para-um ou qualquer propriedade que exija acesso ao banco de dados para ser preenchida. Isso pode anular o propósito de usar oLoad
e resultar em um desempenho pior do que o métodoGet
.Faça uso de
Load
quando precisar apenas da chave: Se você for inserir um objeto que tenha um relacionamento de referência, oLoad
é uma opção ideal, pois evita a busca desnecessária por dados completos no banco de dados da entidade que vai servir apenas como chave estrangeira.Atente-se aos relacionamentos preguiçosos: Se sua entidade possui relacionamentos com outras entidades configurados como "preguiçosos", certifique-se de entender como o NHibernate trata essas situações ao usar o método
Load
. Pode ser necessário cuidar das sessões e das configurações de carga desses relacionamentos.
Conclusão:
Ambos os métodos Get
e Load
têm seus lugares em aplicações NHibernate, e a escolha entre eles depende do contexto em que são utilizados. Ao usar o método Load
de forma correta e com cuidado, você pode melhorar o desempenho da sua aplicação, evitando consultas desnecessárias ao banco de dados. No entanto, é fundamental compreender as diferenças entre esses métodos e as peculiaridades do seu sistema para tomar a melhor decisão.
Lembre-se de sempre considerar o cenário específico em que sua aplicação está inserida, realizando testes de desempenho e análises para determinar a melhor abordagem para recuperar dados usando o NHibernate.
Top comments (2)
Imagine o cenário em que você está inserindo um pedido de um cliente, normalmente utilizamos o Get para obter o Cliente e depois passar a referência dele para o Pedido, algo como:
var cliente = _repoCliente.GetById(idCliente);
var pedido = new Pedido(cliente);
...
_repoPedido.Save(pedido);
Neste cenário um é feito um Hit do Cliente no banco de dados, recuperando todas as informações e relacionamentos do Cliente.
Se fosse utilizando o Load não aconteceria o hit no banco de dados, pois o Load devolve um ClienteProxy, que é aceito pelo NHibernate para colocar a chave do Cliente no insert do Pedido.
Se você precisar de mais alguma informações do Cliente e não apenas da chave o ideal é utilizar o Get, mas se o seu cenário for de usar apenas a chave o Load faz muito sentido.
No cenário acima usamos apenas o Cliente, mas imagine se você tivesse que inserir um pedido para o Cliente A, com 10 produtos, se fosse usado o Load seriam economizados no mínimo 11 Selects no banco de dados, deixando o código que leva ao insert bem mais performático.
Espero ter esclarecido. Se ficou alguma dúvida posta no artigo.
Massa o artigo, mas fiquei como uma dúvida… no caso do Load, qual seria a vantagem de usar-lo? Digo, com o Load você pode ter a chave da entidade apenas e não todo o objeto, o que é performático mas se você já usa a chave pra buscar então você já tem essa informação né? Pelo que entendi então, o Load carrega os dados no primeiro nível da entidade e, sob demanda, vai carregando outras entidades relacionadas (mas se isso for corriqueiro, melhor então usar o Get).