Awais Mahmood
Awais Mahmood

Reputation: 1336

An entity object cannot be referenced by multiple instances of IEntityChangeTracker EF 6

I am developing an application in MVC 5 and EF 6. I am using a generic method to update the entity and an extension method to detect the changed values and properties. When I try to insert updated record, I got the error,

An entity object cannot be referenced by multiple instances of IEntityChangeTracker

My code for Update is:

public void Update(T data)
{
    var originalEntity = db.Set<T>().AsNoTracking().FirstOrDefault(e => e.Id == data.Id);
    var modifiedValues = originalEntity.ModifiedValues<T>(data).ToList();
    for (int i = 0; i < modifiedValues.Count; i++)
    {
       string modifiedField = modifiedValues.ElementAt(i).Key;
       string modifiedValue = modifiedValues.ElementAt(i).Value.ToString();
       PropertyInfo prop = data.GetType().GetProperty(modifiedField, BindingFlags.Public | BindingFlags.Instance);
       string s = prop.PropertyType.GenericTypeArguments.Select(x => x.FullName).SingleOrDefault();
       switch (s)
       {
            case ("System.DateTime"):
            {
                DateTime d = Convert.ToDateTime(modifiedValue);
                prop.SetValue(data, d);
                break;
            }
            case ("System.String"):
            {
                prop.SetValue(data, modifiedValue);
                break;
            }
       }
   }
   Insert(data); // error occurred in this function
   Save();    
}

The code for Insert function is:

public void Insert(T data)
{ db.Set<T>().Add(data); }

at the statement db.Set().Add(data);, the error occurred.

I know this occurs when the entity is already attached to another Context. But in these functions I only use the context object db once but with AsNoTracking(), so this error shouldn't occur.

I looked to answer in this question and modify my Update function as:

db.Entry(data).State = EntityState.Detached;
Insert(data); // error again occurred in this function
Save(); 

But the error still occurs. What is the problem? How can I solve it?

I call the Update function from my COntroller:

private BaseRepository<ABC> g = new BaseRepository<ABC>();
ABC m = new ABC();
m = db.ABCs.Find(id);
m.S107 = "2";
m.D103 = DateTime.Now;
m.S36 = "awais";
g.Update(m);

Upvotes: 0

Views: 1078

Answers (1)

Domysee
Domysee

Reputation: 12854

You are using m = db.ABCs.Find(id);, which attaches the entity to the context.

Try exchanging it with db.ABCs.AsNoTracking().Where(abc => abc.Id == id).First();

From DbSet.Find documentation:

... request is made to the store for an entity with the given primary key values and this entity, if found, is attached to the context and returned. ...

Upvotes: 3

Related Questions