如何恢复分离实体上的更改 [英] How to revert changes on detached entities

查看:134
本文介绍了如何恢复分离实体上的更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是程序的流程:


  1. 获取实体列表并使用它们。这将从上下文中断开/分离所有实体。

  2. 对其中一个实体进行更改并保存。我从上下文加载实体,并将分离的实体的更改(标量属性和关系)应用于新加载的实体。

  3. 我有一个功能,其中用户可以恢复在断开连接的实体上所做的所有更改。以下是我使用的代码:

  1. Fetch a list of entities and use them. This will disconnect/detach all entities from the context.
  2. Make changes on one of the entities and save it. I'm loading the entity from the context and apply the changes (scalar properties and relational) of the detached entity to the freshly loaded entity.
  3. I have a feature where the user can revert all changes made on the disconnected entity. Here's the code I'm using:

    public async Task RevertChanges()
{
    using (var db = new TwinTailDb())
    {
        //Fansubs.Clear();

        if (db.Entry(this).State == EntityState.Detached && Id != 0)
        {
            db.ArchiveEntries.Attach(this);
            await db.Entry(this).ReloadAsync();
        }

        //await db.Entry(this).Collection(a => a.Fansubs).LoadAsync();
    }
}


但是,当我附加分离的实体时,它会抛出此异常:

However, when I attach the detached entity, it throws this exception:


附加信息:附加类型为TwinTail.Entities的实体。 ArchiveEntry'失败,因为同一类型的另一个实体已经具有相同的主键值。当使用附加方法或将实体的状态设置为不变或修改时,如果图中的任何实体具有冲突的键值,则可能会发生这种情况。这可能是因为一些实体是新的,并且尚未接收到数据库生成的键值。在这种情况下,使用添加方法或添加实体状态来跟踪图形,然后根据需要将非新实体的状态设置为不变或修改。

Additional information: Attaching an entity of type 'TwinTail.Entities.ArchiveEntry' 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.

请注意,由于我使用使用语句,上下文会自动处理。

Note that the context is automatically disposed because I'm using the using statement.

我不知道为什么它甚至主键都有冲突,因为自上一个上下文已经被处理以来我甚至没有加载另一个实体。

I'm not sure why it even there is a conflict in the primary key since I didn't even load another entity since the previous context was already disposed.

此外,如果我跳过步骤2 ,我保存实体中的所有更改,它不会抛出异常。我被遗忘在某种程度上仍然被追踪。

Also, if I skip step 2 where I save all changes in the entity, it doesn't throw an exception. I'm left with thinking that somehow it's still being tracked .

编辑:
当我跳过附件时,会发生什么该实体真正分离。

Here's what happens when I skip attaching, proving that the entity is really detached.


附加信息:无法为ArchiveEntry类型的实体调用ReloadAsync成员,因为实体在上下文中不存在。要向上下文添加一个实体,调用DbSet的Add或Attach方法。

Additional information: Member 'ReloadAsync' cannot be called for the entity of type 'ArchiveEntry' because the entity does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet.

严重的是,发生了什么:(

Seriously, what's happening :(

推荐答案

回答我自己的问题。

主要的问题是我处理上下文的生命周期是错误的,另外,附加一个从另一个上下文加载的实体一定会引发错误,在上下文中加载的实体只能在该上下文中使用。

The main problem was that the way I handled the lifetime of context is wrong. Also, attaching an entity that was loaded from another context will surely throw an error. Entities that are loaded in a context should only be used in that context.

我的上下文太短暂,我将调整其生命周期,以便每个事务(数据库进程)都有一个上下文。

My context is too short-lived. I'll adjust its lifetime so that there's one context for every transaction (database process).

这是一个非常详细的文章关于如何解决/设计您的架构: http://mehdi.me/ambient-dbcontext-in -ef6 /

Here's a very detailed article on how to solve/design your architecture: http://mehdi.me/ambient-dbcontext-in-ef6/

修复架构后,可以通过调用以下方式完成重新加载/还原实体:

After fixing the architecture, reloading/reverting an entity can simply be done by calling:

DbContext.Entry(entity).Reload();

这篇关于如何恢复分离实体上的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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