Подтвердить что ты не робот

Свойство "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.

Это выглядит так просто! Я не понимаю!

4b9b3361

Ответ 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

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