C# 财产';Id';是对象的一部分';s键信息,无法修改
我正在使用EntityFramework4.0,但有一个我无法解决的愚蠢问题 我有两张桌子:C# 财产';Id';是对象的一部分';s键信息,无法修改,c#,foreign-keys,entity-framework-4,C#,Foreign Keys,Entity Framework 4,我正在使用EntityFramework4.0,但有一个我无法解决的愚蠢问题 我有两张桌子: 联系人:Id(主键)、值、ContactTypeId(ContactType的外键) 联系人类型:Id(主键)、类型(家庭、手机、工作等) 实体框架创建了以下两个实体: 联系人:Id、值、联系人类型(导航属性) ContactType:Id、类型、联系人(导航属性) 我正在使用以下代码获取联系人并更新该特定联系人的联系人类型: Contact contact = dbContext.Contacts.S
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.
看起来很简单!我不明白 试试看
contact.ContactType = differentContactType;
或
您正在尝试将ContactType(联系人)的Id设置为3。框架创建的实体没有Contact.ContactTypeId属性。它会自动将其删除,并在联系人实体内创建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;
有两种类型的关联。独立关联,其中相关键仅作为导航属性显示。第二种是外键关联,可以使用外键和导航属性更改相关的键。因此,您可以执行以下操作 //选项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);
我正在使用EF4.0和WPF,我遇到了类似的问题,并且。。。。 用一种非常简单的方式找到了解决问题的方法(至少对我来说) 因为,和您一样,我认为更新表中的字段(例如,在您的案例中:Contact)必须很简单,该字段由另一个表(例如,在您的案例中:ContactType)中的foreignkey引用 但是,错误消息: “…是对象密钥信息的一部分,无法修改。” 仅在您尝试更新主键时出现(这根本不是我的意图) 仔细查看了我的EntityModel的XML代码,发现它:
...
...
出于某种原因(可能是我在数据库中犯了一些愚蠢的错误),当Visual Studio从我的数据库中为我自动生成数据模型时,它在表(Contact)中添加了内容,我想在该表中更新字段(ContactTypeID
)一个秒属性ref
(第二行)
我刚刚删除了第二个属性ref
:
在这两种模型中,存储模型和概念模型以及。。。。问题已解决:-)
因此,仍然是这样的:
...
...
更新和插入现在像婴儿一样平稳运行…:-)
因此,最好检查数据模型的XML,以验证只有您的PK列为
PropertyRef
。为我工作…:-) 发生此问题是因为您多次引用同一对象。这不是EF的限制,而是一种安全功能,可确保您不会插入具有两个不同ID的同一对象。因此,要实现您想要做的事情,只需创建一个新对象并将新创建的对象添加到数据库中
**这个问题经常发生在循环内部。如果使用while或foreach循环,请确保新创建的对象位于循环体中
试试这个:
Contact contact = dbContext.Contacts.Single(c => c.contactTypeId == 1234);
contact.contactTypeId = 4;
dbContext.AddObject(contact);
dbContext.SaveChanges();
我在同时从两个不同的上下文编辑相关对象时发生了这种情况。例如:
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();
我的案例有点复杂(因为这显然是很愚蠢的),但本质上这是导致我案例中错误的原因。在我的案例中,我想复制对象,但更改id,所以我使用这个
Common.DataContext.Detach(object);
像符咒一样工作另一个奇怪的行为在我的例子中,我有一个没有任何主键的表。EF本身使用所有列创建复合主键,即:
<Key>
<PropertyRef Name="ID" />
<PropertyRef Name="No" />
<PropertyRef Name="Code" />
</Key>
无论何时执行任何更新操作,它都会引发以下异常:
The property 'Id' is part of the object's key information and cannot be modified.
属性“Code”是对象关键信息的一部分,不能
可以修改
解决方案:从EF图中删除表,然后转到数据库,在产生问题的表上添加主键,然后将表重新添加到EF图中。现在一切就绪,它将有一个键,即
<Key>
<PropertyRef Name="ID" />
</Key>
我希望这能帮助其他人,因为我知道我没有更新PK,我肯定有一个PK。我将PK值数据绑定到菜单栏,以显示当前PK值,这就是问题的原因。首先删除 下一个添加 简单地说
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";
}
在我的例子中,我只是将主键设置为丢失的表,重新执行了mappind edmx,它确实工作了 当你有主键时,你只有这个
<PropertyRef Name="id" />
但是,如果未设置主键,则
<PropertyRef Name="id" />
<PropertyRef Name="col1" />
<PropertyRef Name="col2" />
请注意,Juergen Fink answer是一个解决方案在我的例子中,我创建了一个一起声明和初始化的对象。我只是在构造函数中进行了初始化,或者您可以在需要时初始化对象。在我的例子中,当我删除ID字段的KEY属性时,出现了错误
// [Key]
public long Id { get; set; }
因此,只要将属性放回原来的位置,就可以让一切恢复正常
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
你应该加上
db.Entry(contact).State = EntityState.Detached;
在.SaveChanges()之后 对我来说,问题是由于我的表缺少主键造成的,在为表设置PK后,问题就消失了对不起,我是在执行linq sql而不是EF。在我的情况下,只要在循环中移动对象并相应地增加ID,问题就解决了。非常感谢<代码>新联系人()代码>是一个冗余的初始值设定项!可能是我一直在寻找的