我正在使用Entity Framework 4.0并且遇到了一个我无法弄清楚的愚蠢问题。
我有两张桌子:
实体框架创建了以下两个实体:
我正在使用以下代码获取联系人并更新该特定联系人的联系方式:
Contact contact = dbContext.Contacts.Single(c => c.Id == 12345);
contact.ContactType.Id = 3;
引发以下异常:
The property 'Id' is part of the object's key information and cannot be modified.
看起来很简单!我不明白!
答案 0 :(得分:24)
发生此问题的原因是您多次引用同一个对象。这不是EF的限制,而是一种安全功能,可确保您不会插入具有两个不同ID的同一对象。因此,要实现您要执行的操作,只需创建一个新对象并将新创建的对象添加到数据库中。
**这个问题经常发生在循环中。如果您正在使用while或foreach循环,请确保将新创建的对象INSIDE循环体。
试试这个:
Contact contact = dbContext.Contacts.Single(c => c.contactTypeId == 1234);
contact.contactTypeId = 4;
dbContext.AddObject(contact);
dbContext.SaveChanges();
答案 1 :(得分:15)
框架创建的实体没有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;
答案 2 :(得分:5)
尝试
contact.ContactType = differentContactType;
或
contact.ContactTypeId = 3;
您正尝试将ContactType(联系人)的ID设置为3。
答案 3 :(得分:3)
当我同时从两个不同的上下文编辑相关对象时,我发生了这种情况。例如:
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();
我的情况有点复杂(因为这显然是非常愚蠢的)但实际上这导致了我的错误。
答案 4 :(得分:2)
我正在使用EF 4.0和WPF,我遇到了类似的问题,并且.... 发现问题以一种非常简单的方式解决了它(至少对我而言)。
因为,和你一样,我认为更新表格中的字段(例如在你的情况下:联系)必须很简单,这是由另一个表中的外键引用的(即在你的表中) case: ContactType )。
然而,错误消息: “....是对象关键信息的一部分,无法修改。” 仅在您尝试更新主键时出现(根本不是我的意图)。
仔细查看我的EntityModel的XML代码并找到它:
<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
)秒 PropertyRef
(第二行)。
我刚刚删除了第二个PropertyRef
:
<PropertyRef Name="contactTypeID" />
两者中,商店模型和概念模型和....问题已解决:-)
因此,仍然像:
<EntityType Name="Contact">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="int" Nullable="false" />
...
...
</EntityType>
更新和插入现在像婴儿一样顺利运行....: - )
因此,最好检查数据模型的XML,以验证只有您的PK列为PropertyRef
。为我工作......: - )
答案 5 :(得分:2)
在我的情况下,我有一个没有任何主键的表.EF本身使用所有列创建复合主键,即:。
<Key>
<PropertyRef Name="ID" />
<PropertyRef Name="No" />
<PropertyRef Name="Code" />
</Key>
每当我进行任何更新操作时,都会抛出此异常:
属性“代码”是对象的关键信息的一部分,但不能 被修改。
解决方案:从EF图中删除表,然后转到创建问题的表上的DB add主键,并将表重新添加到EF图中,现在它只有单键,即
。<Key>
<PropertyRef Name="ID" />
</Key>
答案 6 :(得分:2)
首先删除 接下来添加
简单
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";
}
答案 7 :(得分:1)
有两种类型的关联。独立关联,其中相关键仅表示为导航属性。第二个是外键关联,其中可以使用外键和导航属性来改变相关键。所以你可以做到以下几点。
//选项1通用选项
var contacttype = new ContactType{Id = 3};
db.ContactTypes.Attach(contacttype);
customer.ContactType = contacttype;
选项2外键选项
contact.ContactTypeId = 3;
// generic选项适用于外键和独立关联
contact.ContactReference.EntityKey = new EntityKey("container.contactset","contacttypeid",3);
答案 8 :(得分:1)
在我的情况下,我想复制对象,但是更改了id,所以我使用了这个
Common.DataContext.Detach(object);
像魅力一样工作
答案 9 :(得分:1)
在我的情况下,我只是将主键设置为缺少的表,重新完成mappind edmx并且它确实有效 当你有主键时,tou只有这个
{$event->id}
但是如果未设置主键,则可以
<PropertyRef Name="id" />
请注意,Juergen Fink的答案是一个解决方法
答案 10 :(得分:0)
希望这可以帮助别人,经过几个小时的努力,因为我知道我没有更新PK,我肯定有PK。我将PK值数据绑定到菜单栏以显示当前的PK值,这导致了问题。
答案 11 :(得分:0)
在我的情况下,当我删除ID字段的KEY属性时出现了错误。
// [Key]
public long Id { get; set; }
因此,只需将属性放回原处,即可使所有内容再次正常工作!
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
答案 12 :(得分:0)
您应该添加
db.Entry(contact).State = EntityState.Detached;
.SaveChanges()之后;
答案 13 :(得分:0)
对我来说,问题是由于我的表缺少主键引起的,为表设置了PK后问题就消失了
答案 14 :(得分:-2)
就我而言,我正在创建一个一起声明和初始化的对象。我只是在构造函数中初始化过,或者在需要时可以初始化对象。