【发布时间】:2015-10-16 03:51:54
【问题描述】:
我有一堂课Customer。我正在尝试克隆 Customer 对象并对其进行修改,然后我希望将这些修改反映在上下文中(也包括数据库)。我正在使用以下代码来做到这一点。
Customer old = context.Customers.Where(c=>c.CustomerID ==1 ).SingleOrDefault();
Customer m = CustomExtensions.ShallowCopyEntity<Customer>(old);
m.Name = "Modified";
m.MobileNo = "9999999999";
context.Customers.Attach(m);
但它抛出以下异常
附加“DataBindingSample.Customer”类型的实体 失败,因为相同类型的另一个实体已经具有相同的 主键值。使用“附加”方法或 将实体的状态设置为“未更改”或“已修改”(如果有) 图中的实体具有冲突的键值。这可能是因为 一些实体是新实体,尚未收到数据库生成的密钥 价值观。在这种情况下,使用“添加”方法或“添加”实体状态 跟踪图,然后将非新实体的状态设置为 “未更改”或“已修改”(视情况而定)。
我尝试将EntityState 更改为Modified,但没有成功。
谁能告诉我如何做到这一点?
我的主要目标是
- 我想克隆(必要时我将使用深度克隆)现有实体
- 想要修改克隆的实体(以及引用的实体 - 在这种情况下我将使用深度克隆)
- 最后我想保存对数据库的更改
编辑
正如this 评论中指出的那样,我正在尝试附加上下文中存在的对象。因此,如果必须附加,我可以先将其分离,然后再次附加,如下所示。
Customer old = context.Customers.Where(c=>c.CustomerID ==1 ).SingleOrDefault();
Customer m = CustomExtensions.ShallowCopyEntity<Customer>(old);
m.Name = "Modified789789";
m.MobileNo = "9999999999";
((IObjectContextAdapter)context).ObjectContext.Detach(old);
context.Customers.Attach(m);
context.Entry(m).State = EntityState.Modified;
context.SaveChanges();
否则我可以按照this答案中提到的2个选项。
【问题讨论】:
-
在尝试保存之前,您是否尝试为克隆提供新的主键值?
-
@jstreet,不,实际上它不是一个新对象,我想修改一个现有对象。如果我给新的主键它没有意义。
-
问题是,当您克隆现有对象时,它是一个新对象,需要自己的主键。如果您只想修改现有对象,则不应克隆它。你不能同时拥有它。
-
我不明白你为什么要克隆它。根据定义,克隆创造了一些新的东西。它不会修改它。
-
@dman2306 我克隆它的原因是,我以用户将进行所有修改的形式显示客户,这里所有的修改都反映在上下文中(数据绑定)。但是如果用户选择取消所有修改它是不可能的。所以我正在克隆它,以便所有修改都将在克隆对象上完成,如果用户选择保存,最后克隆的对象将被保存。
标签: c# entity-framework