Сначала отключить отслеживание в структуре сущности
Я пытаюсь получить сущность, а затем обновлять ее, но я хочу получить ее без отслеживания, поэтому я могу прикрепить ее к контексту.
У меня есть ссылка EntityFramework.dll
(4.1). Я создал базу данных из модели. (не кодовым).
Получить пользователя:
db.Users.MergeOption = MergeOption.NoTracking;
IQueryable<User> query = db.Users;//.AsNoTracking(); //<-- apparently, this is code-first only.
return query;
Обновить пользователя:
db.Users.Attach(user); //error here.
ObjectStateEntry entry = db.ObjectStateManager.GetObjectStateEntry(user);
entry.SetModifiedProperty(propertyName);
db.SaveChanges();
return user;
Ошибка:
Объект с тем же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом.
Я вызываю метод следующим образом:
var user = userRepository.GetUsers().FirstOrDefault(u => u.UserId == userId);
user.Identifiers.Add(someIdent);
userRepository.UpdateUser(user);
Ответы
Ответ 1
Запросы без отслеживания
Иногда вы можете запрашивать объекты, но не отслеживать сущности контекста. Это может привести к повышению производительности при запросе большого количества объектов в сценариях только для чтения. Метод расширения AsNoTracking выполняет запрос и возвращает результаты без отслеживания их в контексте. В следующем примере запросы возвращают объекты, но они не будут отслеживаться контекстом.
другой
// Query for all departments without tracking them
var departments1 = context.Departments.AsNoTracking().ToList();
// Query for some departments without tracking them
var departments2 = context.Departments
.Where(d => d.Name.StartsWith("math"))
.AsNoTracking()
.ToList();
Ответ 2
Вместо отсоединения и крепления. Если вы хотите обработать обновление элемента, который может быть или не быть из исходного контекста, вы можете сделать следующее.
var originalItem = db.Users.Find(user.UserId);
db.Entry(originalItem).CurrentValues.SetValues(user);
db.SaveChanges();