Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to delete child entities when updating a parent entity in EF 6?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

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)
    {
        // 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);
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading