2016-01-16 2 views
0

Я разрабатываю приложение в MVC 5 и EF 6. Я использую общий метод для обновления объекта и метода расширения для обнаружения измененных значений и свойств. Когда я пытаюсь вставить обновленную запись, я получил ошибку,Объект сущности не может ссылаться на несколько экземпляров IEntityChangeTracker EF 6

Объект объект не может ссылаться несколько экземпляров IEntityChangeTracker

Мой код для обновления является:

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

код для функции вставки:

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

у старейшины t db.Set(). Добавить (данные);, произошла ошибка.

Я знаю, что это происходит, когда объект уже привязан к другому Контексту. Но в этих функциях я использую только контекстный объект db, но с AsNoTracking(), поэтому эта ошибка не должна возникать.

Я посмотрел ответить в this question и изменить свою функцию обновления, как:

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

Но ошибка все еще происходит. В чем проблема? Как я могу это решить?

я вызываю функцию обновления от моего 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); 
+0

Как и где вы извлекаете объект? – Domysee

ответ

3

Вы используете m = db.ABCs.Find(id);, который крепит сущность к контексту.

Попробуйте обменивая ее с db.ABCs.AsNoTracking().Where(abc => abc.Id == id).First();

Из DbSet.Find документации:

... делается запрос в хранилище для объекта с данными первичного ключевых значений и этого объекта, если он найден, прикрепляется к контексту и возвращается. ...