Reputation: 1336
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
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