Обновить часть первичного ключа Entity Framework 4.0
У меня есть таблица с составлением первичного ключа (3 столбца):
UTP_ID (ITEMId)
UTS_ID (CategoryID)
USS_ID (SubCategoryID)
Когда я пытаюсь изменить SubCategory, например, с EF 4, я получаю следующую ошибку:
utl.USS_ID = Convert.ToInt32(ddlSubSetor.SelectedItem.Value);
the property is part of the object key information and cannot be modified
Любые идеи? Почему я не могу его изменить?
Ответы
Ответ 1
EF реализует карту идентичности между значениями свойств первичного ключа и ссылками на объекты. Он не позволяет изменять ключ для одного и того же экземпляра объекта.
Я бы сделал это с помощью прямого SQL:
objectContext.ExecuteStoreCommand(
"UPDATE MyTable SET USS_ID = {0} WHERE UTP_ID = {1} AND UTS_ID = {2} AND USS_ID = {3}",
Convert.ToInt32(ddlSubSetor.SelectedItem.Value),
utl.UTP_ID, utl.UTS_ID, utl.USS_ID);
Убедитесь, что ваш объект utl
отделен от контекста, потому что этот код непосредственно записывается в таблицу базы данных, и сущность не получает никакой информации об этом изменении. Но это позволяет избежать удаления и воссоздания объекта (что может быть невозможно из-за существующих ограничений внешнего ключа в старой строке в базе данных).
Ответ 2
В результате того, что он является частью ключа сущности, объект должен быть удален из контекста и повторно связан с новым значением первичного ключа.
Структура Entity Framework работает с использованием контекста, который управляет состоянием сущностей, набором сущностей (в основном, таблицы) и самой сущностью (строка данных). По мере чтения данных из базы данных она добавляется в коллекцию сущностей, которая, в свою очередь, управляется контекстом для изменения состояния. Изменение ключа Entity действительно удаляет запись из базы данных и вставляет новую. В результате, чтобы изменить ключ сущности, сначала удалите сущность из нее, отделите объект объекта, чтобы разрешить изменение ключа, измените значение первичного ключа и снова присоедините объект к коллекции. Наконец, вызовите сохранение изменений в контексте, чтобы применить изменения к базе данных.
Следующий код должен давать желаемые результаты:
Context.UTLs.DeleteObject(utl);
Context.UTLs.Detach(utl);
Context.SaveChanges();
utl.USS_ID = Convert.ToInt32(ddlSubSetor.SelectedItem.Value);
Context.UTLs.AddObject(utl).
Context.SaveChanges();