EF Core - Usando AsNoTracking com Identity Resolution
Hoje veremos as consequências em usar AsNoTracking com o recurso Identity Resolution disponível a partir da EF Core 5.0. |
Eu já apresentei o conceito Identity Resolution neste artigo, mas de forma bem resumida, o Identity Resolution é usado pelo EF Core para manter uma única instância de uma determinada chave primária.
|
O que é o AsNoTracking ?
O recurso AsNoTracking é uma opção sugerida para tornar as consultas mais rápidas, pois usando este recurso as consultas não passam pela lógica de rastreamento de entidade, e o EF Core apenas vai ao banco de dados e traz os dados para você.
Toda vez que sua aplicação realiza uma consulta, o EF core verifica se o contexto já está rastreando os objetos necessários, em caso positivo, o EF Core retornará dados do contexto. Se o contexto não contiver essas entidades, o EF core fará uma consulta ao banco de dados e os dados retornados pelo banco de dados são usados para criar novas instâncias das respectivas entidades e essas entidades são então anexadas ao contexto.
Exemplo de código usando AsNoTracking:
using (PaisDbContext context = new PaisDbContext()) { WriteLine("-------------Desbilitando o rastreamento ---------------"); var paises = context.Paises.AsNoTracking().ToList(); foreach (var pais in paises) |
Nota: Baseado no projeto criado no artigo : Usando AsNoTracking
Vamos detalhar um pouco mais o funcionamento do rastreamento das entidades e de como o AsNoTracking atua.
As consultas
realizadas pelo EF Core no banco de dados retornam tipos de entidade, e, por
padrão, essas consultas são consultas de rastreamento pois o rastreamento esta
habilitado por padrão no EF Core.
Todas as operações realizadas em uma entidade que está sendo rastreada são
mantidas pelo contexto, e, as alterações não são salvas no banco de dados até
que o método SaveChanges ou SaveChangesAsync seja
chamado.
Assim, toda vez que a aplicação faz uma consulta, o EF core verifica se o contexto já
está rastreando os objetos necessários, e, se o contexto estiver fazendo o
rastreamento, o EF core retornará os dados do contexto. Portanto, os dados são
retornados pelo EF core sem realmente consultar o banco de dados.
Se o contexto não contiver essas entidades, o EF core fará uma consulta ao banco
de dados e os dados retornados pelo banco de dados são usados para criar
novas instâncias das respectivas entidades. Essas entidades são então anexadas
ao contexto.
Sem rastreamento significa Sem Identity Resolution
Quando o
rastreamento está habilitado, o EF Core usa o Identity
Resolution ou resolução de identidade para manter apenas uma única
instância de uma determinada chave primária. Mas quando o
AsNoTracking é usado, a resolução de identidade não é usada pelo EF Core.
O que isto significa ?
Digamos que os
resultados retornados pela consulta contenham a chave primária repetida
várias vezes.
Se o rastreamento estiver ativado, uma única chave primária criará apenas
um único objeto e o anexará ao contexto.
Se o rastreamento NÃO estiver habilitado, para cada linha, um novo objeto
será criado.
Portanto, mesmo que a chave primária seja a mesma, o EF Core criará vários objetos da entidade.
Sentiu o drama !!!!
Usando AsNoTracking com Identity Resolution
No entanto isso mudou a partir do EF Core 5.0.
Antes do EF Core 5.0, não havia como habilitar a resolução de identidade com AsNoTrakcing.
Mas agora, a partir do EF Core 5.0, existe uma API adicional que pode ser usada para habilitar AsNoTracking e usar Identity Resolution ou resolução de identidade.
using
(PaisDbContext context = new
PaisDbContext()) { Console.WriteLine("-------------Desabilitando o rastreamento ---------------"); var paises = context.Paises.AsNoTrackingWithIdentityResolution().ToList();
foreach (var pais in
paises) |
Este código mostra o uso do novo recurso AsNoTrackingWithIdentityResolution.
Aqui, com a API
AsNoTrackingWithIdentityResolution, a resolução de
identidade é habilitada, mas não habilita o rastreamento de entidades.
Portanto, quando uma consulta retorna um conjunto de resultados contendo várias
linhas com o mesmo valor de chave primária, o EF Core cria um único objeto para
um determinado valor de chave primária.
Mas esses objetos não são adicionados para rastreamento.
Essa opção pode
ser útil em alguns cenários para reduzir o número de objetos criados (otimizando
assim o uso da memória).
Isso vem resolver o problema de consultas quando temos um relacionamento entre
as entidades do tipo um para muitos.
Aguarde que veremos qual problema esse novo recurso resolve neste cenário.
Pegue o projeto aqui: EFCoreIdentityResolution.zip
E estamos conversados...
"Orem também
para que sejamos libertos dos homens perversos e maus, pois a fé não é de
todos.
Mas o Senhor é fiel; ele os fortalecerá e os guardará do Maligno."
2 Tessalonicenses
3:2,3
Referências:
ASP .NET Core 5 - CRUD com EF Core 5 usando imagens
EF Core - Fundamentos : Componentes
Usando o EF Core com Windows Forms
EF Core - Usando a abordagem DataBase First - Criando uma
EF Core - Iniciando com o Entity Framework Core