Свойство "Id" является частью информации о ключе объекта и не может быть изменено
Я использую Entity Framework 4.0 и имею глупую проблему, которую я не могу понять.
У меня есть две таблицы:
- Контакт: Идентификатор (первичный ключ), Значение, ContactTypeId (внешний ключ для ContactType)
- ContactType: Id (первичный ключ), тип (домашний, мобильный, рабочий и т.д.).
Entity Framework создала следующие два объекта:
- Контакт: Id, Value, ContactType (свойство навигации)
- ContactType: идентификатор, тип, контакт (свойство навигации)
Я использую следующий код, чтобы получить контакт и обновить тип контакта для этого конкретного контакта:
Contact contact = dbContext.Contacts.Single(c => c.Id == 12345);
contact.ContactType.Id = 3;
Выдает следующее исключение:
The property 'Id' is part of the object key information and cannot be modified.
Это выглядит так просто! Я не понимаю!
Ответы
Ответ 1
Объект, созданный каркасом, не имеет свойства contact.ContactTypeId. Он автоматически удалил его и создал ассоциацию ContactType внутри объекта Contact.
Способ заставить его работать, как вы предположили, - создать объект ContactType, запросив базу данных и назначив ее contact.ContactType. Например:
Contact contact = dbContext.Contacts.Single(c => c.Id == 12345);
ContactType contactType = dbContext.ContactType.Single(c => c.Id == 3);
contact.ContactType = contactType;
Ответ 2
Эта проблема возникает из-за того, что вы ссылаетесь на один и тот же объект более одного раза. Это не ограничение EF, а скорее функция безопасности, гарантирующая, что вы не вставляете один и тот же объект с двумя разными идентификаторами. Таким образом, чтобы добиться того, что вы пытаетесь сделать, просто создайте новый объект и добавьте вновь созданный объект в базу данных.
** Эта проблема часто возникает внутри циклов. Если вы используете цикл while или foreach, убедитесь, что новый созданный объект находится внутри тела цикла.
попробуй это:
Contact contact = dbContext.Contacts.Single(c => c.contactTypeId == 1234);
contact.contactTypeId = 4;
dbContext.AddObject(contact);
dbContext.SaveChanges();
Ответ 3
Try
contact.ContactType = differentContactType;
или
contact.ContactTypeId = 3;
Вы пытаетесь установить Id ContactType (контакта) на 3.
Ответ 4
Я имел это, когда я редактировал связанные объекты из двух отдельных контекстов одновременно. Пример:
DataContext ctxA = new DataContext();
DataContext ctxB = new DataContext();
Author orwell = new Author {Name = "George Orwell" };
ctxA.Add(orwell);
ctxB.Add(new Book {Name = "1984", Author = orwell});
ctxA.SaveChanges();
ctxB.SaveChanges();
Мой случай был немного более запутанным (так как это, очевидно, довольно глупо), но по существу это вызывало ошибку в моем случае.
Ответ 5
Я использую EF 4.0 и WPF, и у меня была схожая проблема, и....
нашел проблему, которая решила его (по крайней мере для меня) очень простым способом.
Поскольку, как и вы, я думал, что должно быть просто обновить поле в таблице (т.е. в вашем случае: контакт), на которое ссылается чужой ключ из другой таблицы (т.е. в вашем случае: ContactType).
Однако сообщение об ошибке:
".... является частью информации о ключе объекта и не может быть изменен".
появляется только при попытке обновить первичный ключ (что не было моим намерением вообще).
Если бы более подробно рассмотрел XML-код моего EntityModel и нашел его:
<EntityType Name="Contact">
<Key>
<PropertyRef Name="ID" />
<PropertyRef Name="contactTypeID" /> <!-- This second line caused my problem -->
</Key>
<Property Name="ID" Type="int" Nullable="false" />
...
...
</EntityType>
По какой-то причине (возможно, я сделал какую-то глупую ошибку в моей базе данных), когда Visual Studio автогенерировала для меня DataModel из моей базы данных, она добавлена в ту самую таблицу (Contact), где я хотел обновить поле (ContactTypeID
) a second PropertyRef
( вторая строка).
Я просто удалил второй PropertyRef
:
<PropertyRef Name="contactTypeID" />
в модели магазина и концептуальной модели и.... проблема была решена:-)
Следовательно, остается следующим:
<EntityType Name="Contact">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="int" Nullable="false" />
...
...
</EntityType>
Обновления и вставки теперь работают плавно, как ребенок....: -)
Следовательно, хорошая идея проверить XML файл данных, чтобы убедиться, что только ваш ПК указан как PropertyRef
. Работал для меня...: -)
Ответ 6
Еще одно странное поведение в моем случае У меня есть таблица без какого-либо первичного ключа .EF сам создает составной первичный ключ, используя все столбцы i.e.:
<Key>
<PropertyRef Name="ID" />
<PropertyRef Name="No" />
<PropertyRef Name="Code" />
</Key>
И всякий раз, когда я выполняю операцию обновления, это исключает это:
Свойство "Код" является частью информации о ключе объекта и не может быть изменен.
Решение: удалите таблицу из диаграммы EF и перейдите в свой DB, добавьте первичный ключ в таблицу, которая создает проблему и снова добавляет таблицу в диаграмму EF, теперь она будет иметь один ключ i.e.
<Key>
<PropertyRef Name="ID" />
</Key>
Ответ 7
сначала Удалить
следующий добавить
для простого
public static IEnumerable UserIntakeFoodEdit(FoodIntaked data)
{
DBContext db = new DBContext();
var q = db.User_Food_UserIntakeFood.AsQueryable();
var item = q.Where(f => f.PersonID == data.PersonID)
.Where(f => f.DateOfIntake == data.DateOfIntake)
.Where(f => f.MealTimeID == data.MealTimeIDOld)
.Where(f => f.NDB_No == data.NDB_No).FirstOrDefault();
item.Amount = (decimal)data.Amount;
item.WeightSeq = data.WeightSeq.ToString();
item.TotalAmount = (decimal)data.TotalAmount;
db.User_Food_UserIntakeFood.Remove(item);
db.SaveChanges();
item.MealTimeID = data.MealTimeID;//is key
db.User_Food_UserIntakeFood.Add(item);
db.SaveChanges();
return "Edit";
}
Ответ 8
Существует два типа ассоциаций. Независимая ассоциация, где связанный ключ будет отображаться только как навигационное свойство. Второй - это ассоциация внешних ключей, где связанный ключ может быть изменен с использованием внешнего ключа и свойства навигации. Поэтому вы можете сделать следующее.
//опция 1 общий вариант
var contacttype = new ContactType{Id = 3};
db.ContactTypes.Attach(contacttype);
customer.ContactType = contacttype;
опция 2 варианта внешнего ключа
contact.ContactTypeId = 3;
//общий вариант работает с внешним ключом и независимой ассоциацией
contact.ContactReference.EntityKey = new EntityKey("container.contactset","contacttypeid",3);
Ответ 9
В моем случае я хочу дублировать объект, но изменить идентификатор, поэтому я использую этот
Common.DataContext.Detach(object);
Работайте как шарм
Ответ 10
в моем случае я просто установил первичный ключ на отсутствующую таблицу, сделал mappind edmx, и он работал, когда у вас есть первичный ключ, который будет иметь только этот
<PropertyRef Name="id" />
однако, если первичный ключ не установлен, вы бы имели
<PropertyRef Name="id" />
<PropertyRef Name="col1" />
<PropertyRef Name="col2" />
обратите внимание, что ответ Юргена Финка является обходной
Ответ 11
Просто надеюсь, что это поможет кому-то еще, после долгих часов с этим, потому что я знал, что я не обновлял ПК, и у меня определенно был ПК. У меня была привязка данных значения PK к строке меню, чтобы показать текущее значение PK, и это вызвало проблему.
Ответ 12
В моем случае ошибка появлялась, когда я удалил атрибут KEY поля ID.
// [Key]
public long Id { get; set; }
Так что, просто положив атрибут обратно на место, все снова заработало!
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
Ответ 13
Вы должны добавить
db.Entry(contact).State = EntityState.Detached;
После .SaveChanges();
Ответ 14
Соло дебесов, созданных в рамках проекта "Обьедо Дентро дель Чикло", "Para Que Cada Vez Que"
Ответ 15
В моем случае я создавал объект, объявленный и инициализированный вместе. Я только что инициализировал в конструкторе или что вы можете инициализировать объект при необходимости.