Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

262
Visualizações
How to discard changes to context in EF Core

I have a huge list of "flattened" objects in json format, and a somewhat complicated relational DB schema (with about 20 tables corresponding to a flattened object). I'm trying to automate the insertions of those flattened objects in my new relational database:

foreach (var flattenedObject in flattenedObjects)
{
    _repository.Insert(flattenedObject).Wait();
    //some time logging, etc
}

The Insert() method callsAddRangeAsync() and AddAsync() for a number of related objects in different tables.

Since the flattened objects are legacy, I'd say about 0.001% of them are malformed and will violate DB constraints - for example trying to insert a duplicate composite primary key in one of the tables.

I expect these rare errors, thus my idea is - wrap the whole Insert() operation in a transaction - if any piece of the operation is invalid, just don't insert anything and log the error, so I can modify the flattened object manually before trying again. Thus my code looks somewhat similar to this:

public async Task Insert(FlattenedObject fo)
{
    using (var transaction = _context.Database.BeginTransaction())
    {
        try
        {
            //magical code that calls AddAsync for multiple tables
        }
        catch (Exception ex)
        {
            transaction.Rollback()
            //logging
        }
    }
}

However, if an error occurs somewhere in my try block (I try to insert an object that violates a composite primary key) my whole context object becomes corrupt.

The object that caused the exception still remains in my DbContext and any following call to AddAsync() in a different transaction triggers a new exception.

I tried recreating my DbContext and repo for every new object in the foreach loop above - but even then if I query:

_context.ChangeTracker.Entries().Where(e => e.State != EntityState.Unchanged);

I see my old object is still in the new instance of dbContext.

Is there any (elegant) way to tell my context to reset all pending changes - so that I can put it in the catch block whenever an error occurs? I want everything that happens within my failed transaction to stay there and not leak.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

The code below worked for me. However, if someone posts a cleaner solution (I still expect there to be something out of the box with EF) I will accept it.

private void ResetContextState() => _context.ChangeTracker.Entries()
    .Where(e => e.Entity != null).ToList()
    .ForEach(e => e.State = EntityState.Detached);
over 4 years ago · Santiago Trujillo Relatório

0

Solution :

After years, maybe some of you are still looking, and by a miracle you are using EF Core 5.0. There is a new feature to clear the ChangeTracker :

dbContext.ChangeTracker.Clear();

Just call it whenever an update fails.
But do not forget that this is not at all the best practice. Microsoft recommends to create new dbContext for each request, as it is designed to have that short lifespan.
More information here : Microsoft EF Core 5.0: ChangeTracker.Clear Method

Better Solution

But bit more complexe, is to use the DbContextFactory. This can be useful when application code needs to create and dispose context instances manually.

More Information here : Microsoft EF Core 5.0 : DbContextFactory
Enjoy

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda