我知道有很多关于我得到的错误的问题,但在同一场景中没有一个问题。我需要在一个"事务"下更新和/或删除一个对象的几个项目。与实体框架。
我有一个项目对象列表,让我们称之为List<ItemObject>
和可以拥有这些项目的对象 - 称之为SuperObject
。 ItemObjects 有一个复杂的主键,由 SuperObject 的主键和该列表中的序列号组成。
场景:用户修改某些项目并将其他项目标记为删除。然后他点击一个按钮保存所有更改。对于我的任务,我需要模拟交易 - 这不是使用EF的好方法,我知道。所以,我需要在项目上设置状态,然后调用ctx.SaveChanges()
。我的问题是,在更新序列号时,我得到多个匹配的主键值(我猜),这引起了臭名昭着的错误:
附加类型&#39; ItemObject&#39;的实体因为另一个实体而失败 相同类型的已经具有相同的主键值...
通过拨打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的概念,所以我无法找到绕过这个错误的方法并仍然满足作业的要求。
答案 0 :(得分:1)
您可以通过分析上下文的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。 轻松调试和修复与上下文相关的问题。 如果这有帮助,请告诉我!
答案 1 :(得分:1)