3

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);
}

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I have updated my question. I quess I have to implement the unitofwork which has the context and passes it to the repositories right?
0

I think the problem is from here:

newAudit.AuditType = auditTypeRepository.Find(model.SelectedAuditTypeId);

Change that like this:

newAudit.AuditTypeId = model.SelectedAuditTypeId;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.