Это беспокоило меня уже некоторое время. Моя проблема заключается в следующем. У меня есть экземпляр типа X , который называется x . X - это класс сущностей, созданный Entity Framework.
Внутри моего метода я получаю x от веб-службы, поэтому он не привязан к контексту моего объекта, но я знаю, что элемент с таким же первичным ключом уже существует в базе данных, поэтому я хочу обнови это. Я добавил следующее тело в метод, и он работал нормально:
objectContext.Xs.Attach(x);
objectContext.ObjectStateManager.ChangeObjectState(x, EntityState.Modified);
objectContext.SaveChanges();
Пока все хорошо. Однако мой objectContext не был создан этим методом, и вдруг этот код перестал работать и выбросил InvalidOperationException
со следующим текстом:
Объект с таким же ключом уже существует в ObjectStateManager. ObjectStateManager не может отслеживать несколько объектов с одним и тем же ключом.
Это произошло потому, что за некоторое время до запуска этого кода был выполнен следующий код:
objectContext.Xs.ToList();
Это считывает все текущие X объекты из базы данных и тем самым добавляет их в ObjectStateManager.
Затем я изменил код следующим образом:
objectContext.Xs.ApplyCurrentValues(x);
objectContext.SaveChanges();
Это сработало нормально, но если я снова удалю строку objectContext.Xs.ToList();
, я получу еще один InvalidOperationException
со следующим текстом:
Объект с ключом, который совпадает с ключом предоставленного объекта, не может быть найден в ObjectStateManager. Убедитесь, что значения ключа предоставленного объекта соответствуют значениям ключа объекта, к которому необходимо применить изменения.
Так что теперь у меня возникла противоположная проблема. Этот метод не работает, потому что он не отслеживается ObjectStateManager.
Кроме того, я не нашел надежного метода определения, отслеживается ли мой x или нет, поэтому в настоящее время я добавил код, подобный следующему:
try
{
objectContext.Xs.Attach(x);
objectContext.ObjectStateManager.ChangeObjectState(x, EntityState.Modified);
objectContext.SaveChanges();
}
catch(InvalidOperationException)
{
objectContext.Xs.ApplyCurrentValues(x);
}
objectContext.SaveChanges();
Это означает, что я использую обработку исключений как обычный программный поток (вряд ли исключение, что элемент уже отслеживается ObjectStateManager), и у меня также есть проблема, что я мог бы поймать другой не связанный InvalidOperationException
, который я должен был обработать по-другому.
Итак, мой вопрос. Кто-нибудь знает хорошее решение для этого или, по крайней мере, правильный способ проверить, отслеживается ли ObjectStateManager x , чтобы я мог выбрать один из методов, основанный на этом, вместо try / catch?