Entity Object attached/not attached to dbContext


Question

I have the following EF data statement :

class Model1{
    public Int32  Id{ get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop3 { get; set; }
    public virtual Model3 PropModel31{ get; set; }
    public virtual Model3 PropModel32{ get; set; }
}
class Model3{
    public Int32  Id{ get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
}

I request my entities in different places :

//db being the datacontext
//Partial view of Model1
var model1s = from model1 in db.Model1
    select new {
                 model1.Id,
                 model1.Prop1,
                 model1.Prop2,
                 model1.PropModel31,
                 model1.PropModel32,
    };

And, later, I am trying to update a model entity,

public ActionResult Save(Model1 model1)
{
    db.Model1.Attach(model1);
    var entry = db.Entry(model1);
    entry.Property(e => e.Prop1).IsModified = true;
    entry.Property(e => e.Prop2).IsModified = true;
    ...
    db.SaveChanges();
}

but I get the following exception :

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

If I comment db.Model1.Attach(model1); then I get the opposite exception :/

Member 'IsModified' cannot be called for property 'Prop1' because the entity of type 'Model1' does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet

So, my guess is that the Model3 entity properties are attached to the context, but how can check that, fix it?

Thank you for your help.

Accepted Answer

Well, the exception is triggered because one of the sub entity property PropModel31 was reset to new (with Id=0).

The exception was not really explicit.

Thanks a million to Andrew Counts for his time and expertise!


Popular Answer

You need a new instance of your DbContext:

public ActionResult Save(Model1 model1)
{
    using (var ctx = new MyDbContext())
    {
        ctx.Model1.Attach(model1);
        var entry = ctx.Entry(model1);
        entry.Property(e => e.Prop1).IsModified = true;
        entry.Property(e => e.Prop2).IsModified = true;
        ...
        ctx.SaveChanges();
    }
}




Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why