我有一个Code First EF 4.1模型,如下所示:
http://pct.staging.xeed.nl/images/model.png
此模型的对象被序列化为JSON,以便使用jQuery在浏览器中处理。在jQuery中,此对象图被实例化为Javascript对象。用户交互(添加/删除操作,添加/删除任务)导致Javascript对象的修改。将新任务或操作对象添加到图形时,它将获得ID = 0.删除任务或操作对象时,将获得ui_status =“已删除”。在用户界面中的保存事件后,修改后的Javascript对象被序列化为JSON并发送到'AssignmentController'。
我的问题是我无法弄清楚保存此对象图的最佳方法是什么。我继续遇到问题,例如:(1)'不允许与处于Deleted状态的实体添加关系'或者(2)'ObjectStateManager中已存在具有相同键的对象'。
(ad 1) - 尝试从任务中删除操作时出现此错误。
(ad 2) - 尝试一次保存2个或更多新对象时出现此错误。新对象都有ID = 0,这可能是导致此错误的原因。
这是我的代码:
// POST: /Assignment/Save/assignment
[HttpPost]
public string Save([Bind(Exclude="date")] Assignment assignment )
{
string message;
assignment.date = DateTime.Now;
Session["currentAssignment"] = assignment;
if (!User.Identity.IsAuthenticated)
{
return "Please Log in first.";
}
if (ModelState.IsValid)
{
assignment.username = User.Identity.Name;
if (assignment.tasks != null)
{
foreach (var task in assignment.tasks.ToList())
{
db.Tasks.Attach(task);
if (task.actions != null)
{
foreach (var action in task.actions.ToList())
{
db.Actions.Attach(action);
if ((task.ui_status == "deleted" || action.ui_status == "deleted"))
{
if (action.actionID > 0)
{
db.Entry(action).State = EntityState.Deleted;
}
else
{ //object was deleted from a new object graph
//just save it with ui_status="deleted", it will be deleted from the db next time around
}
}
else if (action.actionID == 0)
{
db.Entry(action).State = EntityState.Added;
}
else
{
db.Entry(action).State = EntityState.Modified;
}
}
}
if (task.ui_status == "deleted")
{
if (task.taskID > 0)
{
db.Entry(task).State = EntityState.Deleted;
}
else
{ //object was deleted from a new object graph
//just save it with ui_status="deleted", it will be deleted from the db next time around
}
}
else if (task.taskID== 0)
{
db.Entry(task).State = EntityState.Added;
}
else
{
db.Entry(task).State = EntityState.Modified;
}
}
}
db.Assignments.Attach(assignment);
db.Entry(assignment).State = assignment.assignmentID == 0 ? EntityState.Added : EntityState.Modified;
db.SaveChanges();
return js.Serialize(assignment);
}
}
我一直在努力解决这个问题,阅读所有帖子。我认为EF会照顾这样的事情,因为大多数非常重要的应用都会遇到这种情况。
对此的任何想法将不胜感激。
答案 0 :(得分:1)
管理自己解决问题。我首先通过首先将EntityState.Added /EntityState.Modified设置为每个对象来更新对象图。然后我调用db.SaveChanges()并再次运行所有对象以在需要时设置EntityState.Deleted。然后我再次调用db.SaveChanges()。
这是代码:
[HttpPost]
public string Save([Bind(Exclude="date")] Assignment assignment )
{
string message;
assignment.date = DateTime.Now;
Session["currentAssignment"] = assignment;
if (!User.Identity.IsAuthenticated)
{
return "Please Log in first.";
}
if (ModelState.IsValid)
{
assignment.username = User.Identity.Name;
if (assignment.tasks != null)
{
foreach (var task in assignment.tasks.ToList())
{
if (task.actions != null)
{
foreach (var action in task.actions.ToList())
{
db.Entry(action).State = action.actionID == 0 ? EntityState.Added : EntityState.Modified;
}
}
db.Entry(task).State = task.taskID == 0 ? EntityState.Added : EntityState.Modified;
}
}
db.Entry(assignment).State = assignment.assignmentID == 0 ? EntityState.Added : EntityState.Modified;
db.SaveChanges();
if (assignment.tasks != null)
{
foreach (var task in assignment.tasks.ToList())
{
if (task.actions != null)
{
foreach (var action in task.actions.ToList())
{
if ((task.ui_status == "deleted" || action.ui_status == "deleted"))
{
db.Entry(action).State = EntityState.Deleted;
}
}
}
if (task.ui_status == "deleted")
{
db.Entry(task).State = EntityState.Deleted;
}
}
}
db.SaveChanges();
return js.Serialize(assignment);
}
希望这可以帮助将来遇到类似问题的人。