【发布时间】:2016-03-12 11:37:18
【问题描述】:
这是程序的流程:
- 获取实体列表并使用它们。这会将所有实体与上下文断开/分离。
- 对其中一个实体进行更改并保存。我正在从上下文加载实体,并将分离实体的更改(标量属性和关系)应用到新加载的实体。
-
我有一个功能,用户可以恢复对断开连接的实体所做的所有更改。这是我正在使用的代码:
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(); } }
但是,当我附加分离的实体时,它会抛出此异常:
附加信息:附加类型为“TwinTail.Entities.ArchiveEntry”的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后将非新实体的状态设置为“未更改”或“已修改”。
请注意,上下文是自动释放的,因为我使用的是 using 语句。
我不确定为什么即使主键存在冲突,因为我什至没有加载另一个实体,因为之前的上下文已经被释放了。
此外,如果我跳过保存实体中所有更改的步骤 2,它不会引发异常。我一直在想,不知何故它仍在被跟踪。
编辑: 以下是我跳过附加时发生的情况,证明实体确实已分离。
附加信息:无法为“ArchiveEntry”类型的实体调用成员“ReloadAsync”,因为该实体在上下文中不存在。要将实体添加到上下文中,请调用 DbSet 的 Add 或 Attach 方法。
说真的,发生了什么:(
【问题讨论】:
-
您是否在第 2 步中处理上下文?
-
好吧,因为我使用的是“使用”语法,所以它会自动处理。
-
通过 PK 查询持久化实体然后从那时起使用它不是最简单的吗?或者您是否专门尝试恢复为实体之前的确切值,而不是当前的持久值?
-
我已经想到了,但我不希望其他对象保留对旧实体的引用。在架构方面,我想保持相同的参考(更少的移动部件)。是的,我正在尝试将其恢复为持久值。
-
我觉得这与“还原”没有任何关系,而更多的是附加一个分离的实体,所以我发布了另一个问题:stackoverflow.com/questions/35987384/…我应该删除这个还是保持这个开放别人看?
标签: c# .net entity-framework