如何将强类型控制器与EntityObjects一起使用?
我的失败......
首先我尝试了这个:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
db.SaveChanges();
return RedirectToAction("Index");
}
这实际上无法保存对数据库的任何更改。所以,我试图将模型附加到我的ObjectContext:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
db.Attach(Model);
db.SaveChanges();
return RedirectToAction("Index");
}
此操作失败,因为“具有空EntityKey值的对象无法附加到对象上下文”。所以,我试图分配EntityKey:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
Model.EntityKey = (from Department d in db.Department
where d.Id == id
select d).FirstOrDefault().EntityKey;
db.Attach(Model);
db.SaveChanges();
return RedirectToAction("Index");
}
这失败了,因为“ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象。”
这应该如何运作?
答案 0 :(得分:3)
问题是,你所拥有的输入并不是一个完整的模型对象,它具有更改的属性 - 它只是一个新的“开始”,具有你想要在现有实体上覆盖的所有属性。您不发布任何ID属性
这看起来有点冗长,但它是我发现的最好的,所以我在我的项目中做到这一点(调整到你的班级名字,不管失去的东西......):
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
var dbDepartment = (from Department d in db.Department
where d.Id == id
select d).FirstOrDefault() as Department
dbDepartment.Name = Model.Name;
dbDepartment.Color = Model.Color;
// etc, assigning values manually...
try
{
db.SaveChanges();
}
catch (Exception ex)
{
// oops...
}
return RedirectToAction("Index");
}
答案 1 :(得分:1)
尝试db.AttachTo()而不是db.Attach()
如上所述here
“在ObjectContext上调用AttachTo以将对象附加到对象上下文中设置的特定实体。如果对象具有null(在Visual Basic中为Nothing)EntityKey值,也执行此操作。”
编辑:实际上,在这种情况下你可能需要调用ApplyPropertyChanges()。
编辑2:您可以使用以下代码为对象构建实体密钥:
public EntityKey GetEntityKey(string entitySetName, object keyValue)
{
IEnumerable<KeyValuePair<string, object>> entityKeyValues =
new[]
{
new KeyValuePair<string, object>("Id", keyValue)
};
var key = new EntityKey(string.Concat("YOUR_OBJECT_CONTEXT_NAME.", entitySetName), entityKeyValues);
return key;
}
然后你会根据名为'Id'的单个数据库列为实体键调用此类内容:
var entityKey = GetEntityKey(“Customer”,23);
我在自己的EF代码中使用了类似的方法,除了使用Generic类型参数以避免必须使用字符串作为实体类名。
答案 2 :(得分:1)
这个怎么样
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, Department dept)
{
Department tmp = new Department()
{
Id = dept.Id
};
try
{
db.Departments.Attach(dept, tmp);
db.Save();
}
}
也许tmp-part可以在Attach部分之后交换为对UpdateModel的调用,但我不确定。
编辑:只需查看附件(实体e,实体原件)上的文档,它确实用e替换原件(或相应地更新原件或w / e)。
答案 3 :(得分:0)
我不建议在您的MVC应用程序中使用POCO。 您应该使用DTO或模型。
也许您应该先通过id检索对象,然后将参数提供的值替换为edit方法,然后保存更改。 您收到错误是因为您没有首先取消模型。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
var entity=from m in db.Models where m.Id == Model.id select m;
Model entityAttached=entity.FirstOrDefault();
//replace all the new values in you object
db.SaveChanges();
}
或deattach对象,并在您想要在edit方法中保存新值时将其附加回来。