DEV Community

Cristiano Rodrigues for Unhacked

Posted on

Aumentando a performance do NHibernate.

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);
    }
Enter fullscreen mode Exit fullscreen mode

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);
    }
Enter fullscreen mode Exit fullscreen mode

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:

  1. 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 tipo LazyInitializationException.

  2. 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 o Load e resultar em um desempenho pior do que o método Get.

  3. Faça uso de Load quando precisar apenas da chave: Se você for inserir um objeto que tenha um relacionamento de referência, o Load é 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.

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

Collapse
 
cnr_br profile image
Cristiano Rodrigues

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.

Collapse
 
luizantonio_adolphsjuni profile image
Luiz Antonio Adolphs Junior

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