无法在Entity Framework 6中附加现有对象 [英] Unable to attach an existing object in Entity Framework 6

查看:78
本文介绍了无法在Entity Framework 6中附加现有对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类 Customer 。我试图克隆一个 Customer 对象并对其进行修改,然后我希望这些修改能够反映在上下文中(数据库也是如此)。我正在使用以下代码来做到这一点。

I have a class Customer. I am trying to clone a Customer object and modify it, then I want those modifications to be reflected in the context (database as well). I am using following code to do that.

    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'
的实体失败,因为相同类型的另一个实体已经具有相同的
主键值。如果图表中的任何
实体具有相互冲突的键值,则使用附加方法或
将实体的状态设置为不变或已修改时,可能会发生这种情况。这可能是因为
某些实体是新实体,并且尚未收到数据库生成的键
值。在这种情况下,请使用添加方法或已添加实体状态
跟踪图形,然后根据需要将非新实体的状态设置为
未更改或已修改。 / p>

Attaching an entity of type 'DataBindingSample.Customer' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

我尝试将 EntityState 更改为 Modified 但它没有用。

I tried changing EntityState to Modified but it didn't work.

有人可以告诉我如何实现吗?

Can anyone tell me how to achieve this?

我的主要目标是


  1. 我要克隆(必要时将使用深度克隆)现有实体

  2. 要修改克隆的实体(以及引用的实体-在这种情况下,我将使用深度克隆)

  3. 最后,我想将更改保存到数据库

编辑

评论,我正在尝试附加区域中存在的对象上下文。因此,如果必须执行附加操作,那么我可以先将其拆离,然后按如下所示再次附加。

As pointed out in this comment i am trying to attach object which aready exists in context. So i can detach it first and then atttach again as shown bellow if attach is compulsory.

        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();

否则,我可以遵循答案。

Otherwise i can follow 2 options mentioned in this answer.

推荐答案

我可以想到2个选项:


  1. 将更新后的值复制回原始实体加载到您的 DbContext 中,然后保存更改。

  2. 原始实体的更新值,如果用户取消了更新,则将其丢弃。

  1. Copy the updated values back to the original entity loaded into your DbContext and then save changes.
  2. Updated values of the original entity and then discard them if user canceled the update.

选项1

仅复制更新后的值将返回到原始加载的实体。 Automapper 是您执行此类任务的朋友。稍后可以扩展此方法,以允许用户更改实体的模型,而不是数据层对象本身(例如,公开用户可以编辑的有限字段)。

Just copy the updated values back to the originally loaded entity. Automapper is your friend in tasks like this. This approach can later be extended to allow user to change a model of your entity and not the data layer object itself (e.g. to expose a limited number of fields that user can edit).

var entity = context.Customers.SingleOrDefault(c => c.CustomerID == 1);
var updatedEntity = CustomExtensions.ShallowCopyEntity<Customer>(old);

updatedEntity.Name = "Modified";
updatedEntity.MobileNo = "9999999999";

entity.Name = updatedEntity.Name;
entity.MobileNo = updatedEntity.MobileNo;

context.SaveChanges();

如果添加Automapper nuget,则映射(复制)将变得更加容易:

If you add Automapper nuget, then you mappings (copying) will become much easier:

Mapper.CreateMap<Customer, Customer>();
Mapper.Map(updatedEntity, entity);

您的代码如下:

// Configuring mapping. Needs to be done only once.
Mapper.CreateMap<Customer, Customer>();

var entity = context.Customers.SingleOrDefault(c => c.CustomerID == 1);

// Check if entity is null

var updatedEntity = CustomExtensions.ShallowCopyEntity<Customer>(old);

updatedEntity.Name = "Modified";
updatedEntity.MobileNo = "9999999999";

// Copy the updated values back
Mapper.Map(updatedEntity, entity);

context.SaveChanges();

选项2

在原始加载的实体中进行更改,如果用户改变主意并取消了,则将其丢弃。请参阅帖子和帖子,介绍了操作方法。
丢弃整个 DbContext 可能不是一个好选择,以防万一您仍然需要它(duh)。

Make changes in the originally loaded entity and discard them if user changed her mind and canceled. See this post and this post on how to do it. Discarding the whole DbContext might not be a good option in case you still need it (duh).

这篇关于无法在Entity Framework 6中附加现有对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆