修改和/或删除同一事务下的记录

本文关键字:事务 记录 删除 修改 | 更新日期: 2023-09-27 18:06:58

我知道我得到的错误有很多问题,但没有一个是在同一个场景中。我需要在实体框架的一个"事务"下更新和/或删除对象的几个项目。

我有一个项目对象的列表,我们称它为List<ItemObject>,而包含这些项目的对象,我们称它为SuperObjectItemObjects有一个复杂的主键,由SuperObject的主键和该列表中的序列号组成。

场景:用户修改了一些条目,并将其他条目标记为删除。然后单击一个按钮保存所有更改。对于我的任务,我需要模拟一个事务——我知道这不是使用EF的好方法。因此,我需要在项目上设置States,然后调用ctx.SaveChanges()。我的问题是,在更新序列号时,我得到了多个匹配的主键值(我猜),这会引发臭名昭著的错误:

由于另一个实体,附加类型为"ItemObject"的实体失败

调用ctx.Entry(i).State = EntityState.Modified;时崩溃

对于如何解决这个问题有什么想法吗?代码如下:

SuperObject objWithItems = (SuperObject)Session["Super"];
List<ItemObject> itemsToKeep = new List<ItemObject>();
foreach(ItemObject io in objWithItems.Items)
                {
                    if (io.Deletion)
                    {
                        ctx.Entry(io).State = EntityState.Deleted;
                    }
                     else
                        itemsToKeep.Add(io);  
                }
                int serial = 0;
                foreach(ItemObject i in itemsToKeep)
                {
                    i.Serial = ++serial;
                    ctx.Entry(i).State = EntityState.Modified;
                }
                ctx.SaveChanges();
            } 
                return RedirectToAction("Read", new { update = false });
        }

我在这方面很熟练,我还在努力掌握EF的概念,所以我不能找到一种方法来绕过这个错误,仍然满足作业的要求。

修改和/或删除同一事务下的记录

在这种情况下,您的上下文已经保存了您的实体条目,因此它将不允许您添加同一实体的另一个条目。

你需要在你的查询中明确地提到". asnotracking ()"

请参考此网址

中的"No-Tracking Queries"

您可以通过分析上下文的ChangeTracker来调试这个问题。在ctx.SaveChanges()之前添加以下代码,并在循环内使用断点调试应用程序。

        var ctxEnteries = ctx.ChangeTracker.Entries();
        foreach (var entry in ctxEnteries)
        {
            //you can inspect the value like originalvalue, currentvalue, state, etc...
            var state = entry.State;
            var entity = entry.Entity;
        }
        ctx.SaveChanges();

因此您可以准确地找到导致问题的ItemObject。轻松调试和修复与上下文相关的问题。让我知道这是否有帮助!