我正在使用Entity Framework 4.0。我在更新数据库中的数据时遇到问题。我得到了这个例外:
ObjectStateManager中已存在具有相同键的对象。
ObjectStateManager无法使用相同的键跟踪多个对象。
我正在研究关系数据库。以下是3个实体和那里的关系:
1 to * 1 to *
Ceremony -----------> Menu ------------> CourseOption
如果我更新已包含Menus
和CourseOptions
的仪式,一切正常。当我们在更新时在仪式中插入新的Menu
和CourseOption
条目时,问题就出现了。比我上面提到的例外。
更新现有仪式的C#代码
public HttpResponseMessage PutCeremony(int id, Ceremony ceremony)
{
if (ModelState.IsValid && id == ceremony.Id)
{
db.Entry(ceremony).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
return Request.CreateResponse(HttpStatusCode.OK, ceremony);
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
如何摆脱这个问题?请帮忙
修改
今天我花了一整天的时间,我读了很多关于articals和stackoverflow的问题。我找到once a product is fetched from the Context, the context is keeping track of it
所以为什么而不是使用:
db.Entry(ceremony).State = EntityState.Modified;
我用过
db.Entry(db.Ceremonies.Find(ceremony.Id)).CurrentValues.SetValues(ceremony);
现在,通过这样做,更改了异常,并且Ceremony实体属性正在正确更改。但是关于Menus条目和CourseOptions条目的仪式没有更新。请给我建议的人。我是EF的新手。
答案 0 :(得分:1)
更新分离的对象图可能非常困难。 (这里只有一个子集合的例子:https://stackoverflow.com/a/5540956/270591如果你有一个盛大的子集合,那就更复杂了。)
没有通用的方法或简单的方法,比如将状态设置为Modified
(它只将标量属性标记为已更改),并希望它存储所有对象图更改。
要考虑实施此类更新的详细信息:
CourseOptions
的孙子集合Menu
。对于(相对简单)用户在您的特定仪式编辑视图...
CourseOptions
,并在数据库中启用该关系的级联删除CourseOptions
添加到现有Menu
,也无法从Menu
CourseOptions
添加到新的Menu
(并且CourseOptions
应与新菜单一起插入)CourseOption
......代码看起来像这样:
var ceremonyInDb = db.Ceremonies.Include(c => c.Menus)
.Single(c => c.Id == ceremony.Id);
db.Entry(ceremonyInDb).CurrentValues.SetValues(ceremony);
foreach (var menuInDb in ceremonyInDb.Menus.ToList())
if (!ceremony.Menus.Any(m => m.Id == menuInDb.Id))
db.Menus.Remove(menuInDb);
foreach (var menu in ceremony.Menus)
if (!ceremonyInDb.Menus.Any(m => m.Id == menu.Id))
ceremonyInDb.Menus.Add(menu);
db.SaveChanges();
如果某些限制不适用(即用户可以在您的视图中进行更复杂的修改),则代码将更加复杂。但基本思想是从数据库中加载对象图(带有Include
的根和子项以及可能带有Include(...Select(...))
的子项),将原始图与新的分离图进行比较并对原始图应用更改根据与新图表的差异绘制图表。