Search code examples
c#entity-framework-coreef-core-2.0

EF Core 2 throws exception on SaveChanges, after first update for related entities


I ran in to a problem with editing/updating entries in db which has related entities. I am able to edit any entry once, and after that I am not able to update any dependent entity which has the same principal entity, as the entity I already modified

I have spent last 5 days or so, trying to solve this. all the advice that I have found on the net, did not work.

you can see the project @: https://github.com/nedimbih/WorkNotes

problematic part is this:

public partial class Work
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    

    public virtual Worker Worker { get; set; }

    public DateTime Date { get; set; }
    public TimeSpan StartingTime { get; set; }
    public float Duration { get; set; }
    public string Note { get; set; }
}

and

public partial class Worker : IdentityUser
{

    public Worker() => WorksDoneByWorker = new HashSet<Work>();

  
    public virtual  ICollection<Work> WorksDoneByWorker { get; set; }
}

In WorkRepository.cs I have this code

 internal int Update(Work input)
    {

        Work workInDb = _context.WorkList
                                .Include(w => w.Worker)
                                .FirstOrDefault(w => w.Id == input.Id);

        if (workInDb != null)
        // v.1
        // {workInDb = input;}
        // v.2
        {
            workInDb.Note = input.Note;
            workInDb.StartingTime = input.StartingTime;
            workInDb.Duration = input.Duration;
            workInDb.Date = input.Date;
            workInDb.Worker = input.Worker;
        }
        int savedEntries;
        try
        {
            savedEntries = _context.SaveChanges();
        }
        catch (Exception)
        {
            savedEntries = 0;
            // used as a flag. Calling code acts upon it
        }
        return savedEntries;
    }

I can make updates on work entries only once, for a given worker.
after I edit/update one work entry (savedEntries holds value 2), I can no longer update any entry with same worker as updated entry. I get exception on SaveChanges saying that Worker with same id is already being tracked.
if I turn of line workInDb.Worker=input.Worker then it saves, but that is not functionality that I need.
if I turn on v.1 code instead of v.2 I get no exception but SaveChanges does nothing.
count of modified entries (in context) is 0 in both cases.


Solution

  • I don't think your model is right. Try this:

    public partial class Work
    {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    
    public int WorkerId { get; set; }
    public Worker Worker { get; set; }
    
    public DateTime Date { get; set; }
    public TimeSpan StartingTime { get; set; }
    public float Duration { get; set; }
    public string Note { get; set; }
    }
    

    and the instead of setting the worker set its Id like this:

     workInDb.WorkerId = input.Worker.Id;
    

    This will prevent EF of trying to create and store a new Worker with the same Id, but instead in adding a relation to the existing worker.