Excluir objetos carregados e descarregados por ID no EntityFrameworkCore
Eu tenho um método que recebe umIEnumerable<Guid>
de IDs para objetos que quero excluir. Um método sugerido é o seguinte
foreach(Guid id in ids)
{
var tempInstance = new MyEntity { Id = id };
DataContext.Attach(tempInstance); // Exception here
DataContext.Remove(tempInstance);
}
Isso funciona bem se os objetos ainda não estiverem carregados na memória. Mas meu problema é que, quando eles já estiverem carregados, oAttach
método lança umInvalidOperationException - The instance of entity type 'MyEntity' cannot be tracked because another instance with the key value 'Id:...' is already being tracked
. O mesmo acontece se eu usarDataContext.Remove
sem ligarAttach
.
foreach(Guid id in ids)
{
var tempInstance = new MyEntity { Id = id };
DataContext.Remove(tempInstance); // Exception here
}
Eu não quero usarDataContext.Find
para capturar a instância de um objeto já carregado, porque isso carregará o objeto na memória, se ainda não estiver carregado.
Não posso usarDataContext.ChangeTracker
para encontrar objetos já carregados porque apenas objetos com estado modificado aparecem lá e meus objetos podem ser carregados e não modificados.
A abordagem a seguir lança o mesmoInvalidOperationException
ao definirEntityEntry.State
, mesmo quando eu substituoGetHashCode
eEquals
emMyEntity
para garantir que as pesquisas no dicionário as vejam como o mesmo objeto.
foreach(Guid id in ids)
{
var tempInstance = new MyEntity { Id = id };
EntityEntry entry = DataContext.Entry(tempInstance);
entry.State == EntityState.Deleted; // Exception here
}
Até agora, a única maneira de descobrir que posso excluir objetos por ID sem saber se o objeto é o seguinte:
foreach(Guid id in ids)
{
var tempInstance = new MyEntity { Id = id };
try
{
DataContext.Attach(tempInstance); // Exception here
}
catch (InvalidOperationException)
{
}
DataContext.Remove(tempInstance);
}
É estranho que eu possa ligarDataContext.Remove(tempInstance)
sem erro após experimentar uma exceção tentandoAttach
mas, neste ponto, ele funciona sem exceção e também exclui as linhas corretas do banco de dados quandoDataContext.SaveChanges
É executado.
Eu não gosto de pegar a exceção. Existe uma maneira "boa" de conseguir o que eu quero?
Nota: Se a classe tiver uma auto-referência, você precisará carregar os objetos na memória para que EntityFrameworkCore possa determinar em qual ordem excluir os objetos.