Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding record duplicates other object using entity framework

I am trying to add a new record in an MVC controller method using Entity framework. When i just used "InsertOrUpdate" the audittype got duplicated. Based on the answer from Entity Framework adding record with a related object i hoped to fix it pretty qiock. This is the code I have right now:

Controller:

if (ModelState.IsValid)
{
    Audit newAudit = Factory.GetNew();
    newAudit.Name = model.Name;
    newAudit.Deadline = model.Deadline;
    newAudit.AuditType = auditTypeRepository.Find(model.SelectedAuditTypeId);

    Repository.InsertOrUpdate(newAudit);
    Repository.Save();

    return RedirectToAction(MVC.Audits.Details(newAudit.Id)); 
}

Repository:

public override void InsertOrUpdate(Qdsa.WebApplications.AuditMaster.Data.Audit model)
{
    if (model.Id == default(int))
    {
        // New entity
        context.Audits.Add(model);
    }
    else
    {
        // Existing entity
        model.ModifiedOn = DateTime.Now;
        context.Entry(model).State = EntityState.Modified;
    }
    //If I leave out the code below the AuditType will be duplicated
    if (model.AuditType != null)
    {
        context.Entry<AuditType>(model.AuditType).State = EntityState.Unchanged;
    }
}

public virtual void Save()
{
    context.SaveChanges();
}

So i thought I fixed the problem. However, AuditType has Child objects too. And now these childobjects get duplicated. What is the right way to add entities with child objects which already exists? Because the AuditType is required I can't save it without first and then update it. any suggestions?

UPDATE: Both the AuditRepostory and the AuditTypeRepository inherit from BaseRepository which has the context as:

protected DBContext context = new DBContext ();

public virtual T Find(int id)
{
    return All.SingleOrDefault(s => s.Id == id);
}
like image 278
amaters Avatar asked Feb 18 '26 05:02

amaters


1 Answers

I can imagine two reasons for the problem:

  • Either auditTypeRepository.Find performs a no tracking query (with .AsNoTracking())
  • Or you are using a context instance per repository, so that Repository and auditTypeRepository are working with two different contexts which will indeed result in a duplication of the AuditType because you don't attach it to the the context that corresponds with Repository (except in the line with your comment).

If the latter is the case you should rethink your design and inject a single context instance into all repositories instead of creating it inside of the repositories.

like image 63
Slauma Avatar answered Feb 19 '26 20:02

Slauma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!