Обновление части первичного ключа Entity Framework 4.0 - PullRequest
7 голосов
/ 18 октября 2011

У меня есть таблица с составным первичным ключом (3 столбца):

UTP_ID (ITEMId)
UTS_ID (CategoryID)
USS_ID (SubCategoryID)

Когда я пытаюсь изменить подкатегорию, например, с EF 4, я получаю следующую ошибку:

utl.USS_ID = Convert.ToInt32(ddlSubSetor.SelectedItem.Value);

the property is part of the object's key information and cannot be modified

Есть идеи? Почему я не могу это изменить?

Ответы [ 2 ]

7 голосов
/ 18 октября 2011

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 отделена от контекста, поскольку этот код напрямую записывается в таблицу базы данных, а сущность не получает никакой информации об этом изменении. Но это избавляет от необходимости удалять и воссоздавать сущность (что может быть невозможно из-за существующих ограничений внешнего ключа для старой строки в базе данных).

1 голос
/ 18 октября 2011

В результате того, что объект является частью ключа объекта, он должен быть удален из контекста и повторно присоединен с новым значением первичного ключа.

Entity Framework работает с наличием контекста, который управляет состоянием сущностей, коллекцией сущностей (в основном, таблицей) и самой сущностью (строкой данных). Когда данные считываются из базы данных, они добавляются в коллекцию объекта, которая, в свою очередь, управляется контекстом для изменения состояния. Изменение ключа сущности действительно удаляет запись из базы данных и вставляет новую. В результате, чтобы изменить ключ объекта, сначала удалите объект из его коллекции, отсоедините объект объекта, чтобы разрешить изменение ключа, измените значение первичного ключа и повторно присоедините объект к коллекции. Наконец, вызовите сохранить изменения в контексте, чтобы применить изменения к базе данных.

Следующий код должен дать желаемые результаты:

Context.UTLs.DeleteObject(utl);
Context.UTLs.Detach(utl);
Context.SaveChanges();
utl.USS_ID = Convert.ToInt32(ddlSubSetor.SelectedItem.Value);
Context.UTLs.AddObject(utl).
Context.SaveChanges();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...