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.
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.