Estamos enfrentando um grande problema de desempenho após atualizar o EF Core 2.2 para o EF Core 3.0. Imagine um modelo de dados simples com uma única propriedade de navegação de coleção e centenas de campos (a realidade parece ainda mais sombria):
public class Item
{
[Key]
public int ItemID {get;set;}
public ICollection<AddInfo> AddInfos {get;set;}
... // consisting of another 100+ properties!
}
e
public class AddInfo
{
[Key]
public int AddInfoID {get;set;}
public int? ItemID {get;set;}
public string SomePayload {get;set;}
}
Durante a recuperação do item, estamos consultando da seguinte maneira:
...
var myQueryable = this._context.Items.Include(i => i.AddInfos).Where(**some filter**);
... // moar filters
var result = myQueryable.ToList();
Em frente, até este ponto.
No EF 2.2, buscar esses resultados consultáveis em duas consultas separadas, uma para Item
e uma para o AddInfo
nível. Essas consultas geralmente buscam 10.000 items
e cerca de 250.000 AddInfos
.
No EF Core 3.0, no entanto, uma única consulta está sendo gerada; a união AddInfo
à esquerda à Item
primeira vista parece ser a melhor opção. Item
No entanto, nosso campo precisa ser buscado com todos os mais de 100 campos, e é por isso que não é possível projetar em uma classe menor ou em um tipo anônimo (adicionar uma chamada ao método .Select (...) -). Portanto, o conjunto de resultados possui tanta redundância (cada Item
aproximadamente 25 vezes) que a consulta em si leva muito tempo para ser executada em um tempo aceitável.
O EF-Core 3.0 oferece alguma opção que nos permita voltar ao comportamento de consulta do bom e velho EF Core 2,2 vezes sem grandes alterações em nosso modelo de dados? Já estamos lucrando com essa mudança em outras partes do aplicativo, mas não nesse cenário específico.
Muito obrigado antecipadamente!
Atualizar
Após uma investigação mais aprofundada, descobri que esse problema já foi resolvido com a Microsoft aqui e fora da caixa, parece não haver maneira de configurar a execução da consulta dividida.
fonte
Respostas:
De acordo com a atualização da minha pergunta inicial, os insights chegaram ao ponto de garantir a mim mesmo que, atualmente, não há realmente nenhuma configuração incorporada para retornar à execução da consulta dividida.
No entanto, a MS forneceu exemplos de código sobre como fazer isso com alterações mínimas de código (para o nosso caso de uso!) Aqui .
Estamos simplesmente removendo as chamadas .Include (...) para as propriedades de navegação da coleção (relações 1: n no nosso caso, relações 1: 1 não são afetadas!). Depois de buscar os itens, estamos simplesmente fazendo outra chamada usando:
Isso busca as entidades de propriedades de navegação da coleção e - se o rastreamento de alterações estiver ativado - preenche automaticamente as coleções nos itens individuais da
result
variável.fonte