This is my entities:
public class Question
{
public int Id { get; set; }
public string Text { get; set; } = string.Empty;
public ICollection<Answer> Answers { get; set; } = new List<Answer>();
public TimeSpan TimeForAnswer { get; set; }
public int TestId { get; set; }
}
public class Answer
{
public int Id { get; set; }
public string Text { get; set; } = string.Empty;
public int QuestionId { get; set; }
public int Points { get; set; }
}
If I update just my parent entity:
public void Update(Question entity)
{
_dbContext.Questions.Update(entity);
}
EF will add/update child entities, but not delete if any missing. I searched, and found this post. And modified my method like this:
public void Update(Question entity)
{
var existingParent = _db.Questions
.Include(p => p.Answers)
.SingleOrDefault(p => p.Id == entity.Id);
if (existingParent != null)
{
existingParent.Answers.Clear();
}
_db.Questions.Update(entity);
}
And now I 'am getting this error:
System.InvalidOperationException: The instance of entity type 'Question' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
How to fix this?
CodePudding user response:
The call to:
_db.Questions.Update(entity);
tries to start tracking entity, but it's already being tracked by the query:
var existingParent = _db.Questions
.Include(p => p.Answers)
.SingleOrDefault(p => p.Id == entity.Id);
I'd go for:
public void Update(Question entity)
{
var existingParent = _db.Questions
.Include(p => p.Answers)
.SingleOrDefault(p => p.Id == entity.Id);
if (existingParent != null)
{
// Update Parent Entity Properties
existingParent.Text = entity.Text;
existingParent.TimeForAnswer = entity.TimeForAnswer;
existingParent.TestId = entity.TestId;
// remove existing from tracked Question
existingParent.Answers.Clear();
// add answers from Question in method param
existingParent.Answers.AddRange(entity.Answers);
}
else
{
// Add the question with answers to the db
_db.Questions.Add(entity);
}
}