【发布时间】:2016-09-14 21:51:13
【问题描述】:
我知道有很多关于我遇到的错误的问题,但没有一个问题出现在同一场景中。我需要在与实体框架的一个“事务”下更新和/或删除对象的多个项目。
我有一个项目对象列表,我们称之为List<ItemObject> 和可以拥有这些项目的对象 - 称之为SuperObject。 ItemObjects 有一个复杂的主键,由 SuperObject 的主键和该列表中的序列号组成。
场景:用户修改了一些项目并将其他项目标记为删除。然后他单击一个按钮以保存所有更改。对于我的任务,我需要模拟一个事务——我知道这不是使用 EF 的好方法。所以,我需要在项目上设置状态,然后调用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 的概念,所以我想不出解决这个错误并仍然满足作业要求的方法。
【问题讨论】:
-
SaveChanges应该为您处理所有事务 -
@SamIam 我不知道,但我知道我仍然收到错误
-
错误是 io 中的某些条目确实具有相同的 Id(或该对象的任何 PK 名称)值。要么您添加了两次相同的项目,要么您的 id 值未正确初始化。由于 Entry() 方法将对象附加到上下文,因此这些行中的任何一行都可能导致此异常。如果所有条目都具有正确的 id 值,则 SaveChanges() 调用将在单个事务中保留上下文中的更改(或 changetracker,因为它还将跟踪所有相关条目)。
标签: c# entity-framework asp.net-mvc-5 primary-key