我有一个Code First EF 4.1模型,看起来像这样:
http://pct.staging.xeed.nl/images/model.png该模型的对象被序列化为JSON,在浏览器中使用jQuery进行处理。在jQuery中,这个对象图被实例化为Javascript对象。用户交互(添加/删除操作和添加/删除任务)会导致对Javascript对象的修改。当一个新的任务或动作对象被添加到图中时,它将得到ID = 0。当一个任务或动作对象被删除时,它会得到ui_status= " deleted "。在用户界面中发生保存事件时,修改后的Javascript对象被序列化为JSON并发送给' AssignmentController '。
我的问题是,我不知道什么是最好的方式来处理保存这个对象图。我一直遇到的问题得到错误像(1)'添加一个关系的实体是在删除状态是不允许的'或(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会处理这样的事情,因为大多数重要的应用程序都会遇到这样的问题。
自己解决了这个问题。我首先通过设置EntityState来更新对象图。/EntityState补充道。修改到每个对象。然后调用db.SaveChanges()并再次遍历所有对象来设置EntityState。必要时删除。然后再次调用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);
}
希望这对将来遇到类似问题的人有所帮助。