属性"Id"是对象的关键信息的一部分,无法修改

Cae*_*sar 38 c# foreign-keys entity-framework-4

我正在使用Entity Framework 4.0并且有一个我无法弄清楚的愚蠢问题.

我有两张桌子:

  1. 联系人:Id(主键),Value,ContactTypeId(ContactType的外键)
  2. ContactType:Id(主键),类型(Home,Cell,Work等)

实体框架创建了以下两个实体:

  1. 联系方式:Id,Value,ContactType(导航属性)
  2. ContactType:Id,Type,Contact(Navigation Property)

我正在使用以下代码获取联系人并更新该特定联系人的联系人类型:

Contact contact = dbContext.Contacts.Single(c => c.Id == 12345);
contact.ContactType.Id = 3;
Run Code Online (Sandbox Code Playgroud)

引发以下异常:

The property 'Id' is part of the object's key information and cannot be modified.
Run Code Online (Sandbox Code Playgroud)

看起来很简单!我不明白!

AL-*_*imi 26

出现此问题的原因是您多次引用同一对象.这不是EF的限制,而是一种安全功能,可确保您不会插入具有两个不同ID的同一对象.因此,要实现您要执行的操作,只需创建一个新对象并将新创建的对象添加到数据库中.

**这个问题经常发生在循环中.如果您使用while或foreach循环,请确保将新创建的对象INSIDE循环体.

试试这个:

Contact contact = dbContext.Contacts.Single(c => c.contactTypeId == 1234);
contact.contactTypeId = 4;
dbContext.AddObject(contact);
dbContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

  • `new Contact();`是一个冗余初始化程序! (3认同)
  • 在我的情况下,只需在循环内移动对象并相应地增加ID就可以解决问题.非常感谢!!!!! (2认同)

Cae*_*sar 16

框架创建的实体没有contact.ContactTypeId属性.它会自动删除它并在Contact实体中创建ContactType关联.

正如您所建议的那样,让它工作的方法是通过查询数据库并将其分配给contact.ContactType来创建ContactType对象.例如:

Contact contact = dbContext.Contacts.Single(c => c.Id == 12345);
ContactType contactType = dbContext.ContactType.Single(c => c.Id == 3);
contact.ContactType = contactType;
Run Code Online (Sandbox Code Playgroud)


gar*_*arh 6

当我同时从两个不同的上下文编辑相关对象时,就发生了这种情况。例子:

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();
Run Code Online (Sandbox Code Playgroud)

我的情况有点复杂(因为这显然很愚蠢),但本质上这导致了我的情况的错误。


小智 6

你应该添加

 db.Entry(contact).State = EntityState.Detached;
Run Code Online (Sandbox Code Playgroud)

在 .SaveChanges(); 之后


Dav*_*haw 5

尝试

contact.ContactType = differentContactType;
Run Code Online (Sandbox Code Playgroud)

要么

contact.ContactTypeId = 3;
Run Code Online (Sandbox Code Playgroud)

您正尝试将ContactType(联系人)的ID设置为3.