在搜索Stack Overflow和Google时,我无法找到明确的答案,希望有人能指出我正确的方向。
我的情况 我希望能够使用单个编辑表单(在单个视图中)使用ASP.NET MVC 3和Entity Framework 4 CTP(代码优先)更新3级深层次结构实体 - 该模型由服务组成,它可以有许多服务选项,它们可以有很多库存物品。
我原本希望能够使用MVC默认模型绑定器(通过TryUpdateModel)来:
我的模特
[Bind(Include="Name, ServiceOptions")]
public class Service {
[Key]
public int ServiceID { get; set; }
public string Name { get; set; }
public DateTime DateCreated { get; set; }
public virtual ICollection<ServiceOption> ServiceOptions { get; set; }
}
[Bind(Include="ServiceOptionID, Description, Tags")]
public class ServiceOption {
[Key]
public int ServiceOptionID { get; set; }
public int ServiceID { get; set; } /* parent id reference */
public string Description { get; set; }
public virtual ICollection<Inventory> InventoryItems { get; set; }
}
[Bind(Include = "InventoryID, Description")]
public class Inventory {
[Key]
public int InventoryID { get; set; }
public int ServiceOptionID { get; set; } /* parent id reference */
public string Description { get; set; }
}
理想的控制器方法:
[HttpPost]
public ActionResult EditService(int id) {
Service service = db.Services.Single(s => s.ServiceID == id);
TryUpdateModel(service); // automatically updates child and grandchild records
if (ModelState.IsValid) {
db.SaveChanges();
return RedirectToAction("Index");
}
return View(service);
}
有没有办法实现这个乌托邦式的梦想,还是我咆哮着错误的树?我愿意使用其他技术(例如普通EF4,Automapper等)
提前致谢!
答案 0 :(得分:0)
只使用默认的模型绑定器?可能不是。
有自定义吗?可能。
但是,您的问题不是模型绑定器本身。您的问题是EF和ORM以及(我认为)一般不会考虑从集合中删除项目作为删除操作。实际上,您告诉ORM的是关系不存在,而不是需要删除子行。根据您的映射,您通常会收到“发生参照完整性约束违规”之类的错误。这不是因为代码首先这就是EF的工作方式。
EF通过设计以这种方式工作,对于更复杂的关系非常重要,例如当你有m2m关系引用其他m2m关系时。你真的希望EF能够消除删除关系的呼叫的歧义,并且要求完全删除一行。
此外,恕我直言,这种技术也很糟糕,因为你让负责映射http值的代码片段也决定了对象应该如何持久化。这是一个糟糕的举动。我认为删除操作是一个非常神圣不可侵犯的行为,不应该单独留给ModelBinder。没有软删除或记录删除对象应被视为“严肃的业务”。