我在我的EF上下文中有Issues
和Scopes
之间的多对多关系。在ASP.NET MVC中,我创建了一个Edit窗体,允许用户编辑特定的Issue。在表单的底部,有一个复选框列表,允许他们选择适用于此问题的范围。在编辑问题时,它可能会一直有一些与它关联的范围 - 这些框将被检查。但是,用户有机会检查更多范围或删除一些当前检查的范围。我的代码看起来是这样的,以节省只是问题:实体框架更新实体以及子实体(根据需要添加/更新)
using (var edmx = new MayflyEntities())
{
Issue issue = new Issue { IssueID = id, TSColumn = formIssue.TSColumn };
edmx.Issues.Attach(issue);
UpdateModel(issue);
if (ModelState.IsValid)
{
//if (edmx.SaveChanges() != 1) throw new Exception("Unknown error. Please try again.");
edmx.SaveChanges();
TempData["message"] = string.Format("Issue #{0} successfully modified.", id);
}
}
所以,当我试图在逻辑添加到保存相关领域,我试过几件事情,但最终,这是什么做的最有意义的对我说:
using (var edmx = new MayflyEntities())
{
Issue issue = new Issue { IssueID = id, TSColumn = formIssue.TSColumn };
edmx.Issues.Attach(issue);
UpdateModel(issue);
foreach (int scopeID in formIssue.ScopeIDs)
{
var thisScope = new Scope { ID = scopeID };
edmx.Scopes.Attach(thisScope);
thisScope.ProjectID = formIssue.ProjectID;
if (issue.Scopes.Contains(thisScope))
{
issue.Scopes.Attach(thisScope); //the scope already exists
}
else
{
issue.Scopes.Add(thisScope); // the scope needs to be added
}
}
if (ModelState.IsValid)
{
//if (edmx.SaveChanges() != 1) throw new Exception("Unknown error. Please try again.");
edmx.SaveChanges();
TempData["message"] = string.Format("Issue #{0} successfully modified.", id);
}
}
但不幸的是,这只是抛出以下异常:
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
我在做什么错?
这很完美!看着SQL事件探查器,对于.Load()来说,这只是一个“额外”的数据库调用,但是与我过去用存储过程手动执行的方式相比,添加/删除更加简洁。谢谢! – Jorin 2010-05-13 06:10:17
詹姆斯很好的答案。这是许多应用程序中的常见问题(有效添加/删除标签)。系统级功能是不是没有充满代码的屏幕?像* issue.Scopes.ReplaceWith(myScopes); * – TFD 2010-05-13 11:00:41
@ TFD是的,我听到你。如果不这样做,英孚团队有很多东西,一个简单的扩展方法可以做到这一点,虽然正确吗? – 2010-05-14 00:52:56