EF Core 'another instance is already being tracked'

前端 未结 4 820
情书的邮戳
情书的邮戳 2021-01-11 18:30

I have a problem updating an entity in .Net Core 2.2.0 using EF Core 2.2.3.

An error occurred while saving changes. Error details: The instance of

相关标签:
4条回答
  • 2021-01-11 18:39

    So, in the end we ended up using a custom UpdateEntity method to save our changes on some entities. This method goes through each property, navigation property and collection property of an entity, makes sure there is no chain and updates the objects a single time.

    It works for big objects and we only use it in those cases. For simple operations we keep using the simple Update

    Here is the link to a bitbucket repository with the source code

    In order to use this method, you will have to get the db entity first. Then call UpdateEntity method with the db entity and your entity received by the request.

    I hope it helps you as it helped me. Cheers!

    0 讨论(0)
  • 2021-01-11 18:45

    I had the same issue but trying to add a second row to the same Entiy. In my case it was because I was assuming the primary key was an Int Identity and auto-generated. As I wasn't assigning any value to it, the second row had the same Id, which is cero default. Lesson learned, when you see this error during an Add() operation in EF, make sure your key is IDENTITY if that's your intention.

    0 讨论(0)
  • 2021-01-11 18:51

    I was trying to update the same data without noticing. It took me ten hours to realize that. If you have duplicate values like mine,i suggest remove that data... The person who reading this answer may have tried all the solutions on the internet like me, ruined the project, stuck the same error, and omitted duplicate data just like me. You are not alone my friend.

    model.GroupBy(gb => gb.ID).Select(s=>s.First()).ToList();//remove duplicates!!!!!
    
    0 讨论(0)
  • 2021-01-11 18:56

    By default when you retrieve entities they are tracked and since they are tracked you could just call SaveChanges and not call Update. You can also retrieve entities without tracking them by using .AsNoTracking()

    calling Update is needed if not tracked already, so if you use AsNoTracking then you do need to use Update before SaveChanges

    public IQueryable<Anomaly> GetAll()
    {    return _context.Anomalies
        .Include(a => a.Asset)
        .Include(a => a.Level);
    }
    
    public async Task<Anomaly> GetAnomaly(int anomalyId, User user)
    {
        var anomaly = await GetAll()
            .AsNoTracking()
            .FirstOrDefaultAsync(a => a.Id == anomalyId);
    
        return anomaly;
    }
    

    You can also check if the entity is tracked to know whether to call Update or not:

    using (var transaction = _context.Database.BeginTransaction())
    {
        try
        {
    
            bool tracking = _context.ChangeTracker.Entries<Anomaly>().Any(x => x.Entity.Id == anomaly.Id);
            if (!tracking)
            {
                _context.Anomalies.Update(anomaly);
            }
    
            _context.SaveChanges();
    
            transaction.Commit();
        }
        catch (Exception ex)
        {
            transaction.Rollback();
            throw;
        }
    }
    
    0 讨论(0)
提交回复
热议问题