ASP.NET MVC3 父子关系和Entity Framework,如何更新子项?
我有一个 ASP.NET MVC 3 应用程序,使用 Entity Framework 4 来处理数据访问。
我的视图模型对象结构如下所示:
public class OrderViewModel
{
public int Id { get; set; }
/* ... */
public List<OrderLineItemViewModel> LineItems { get; set; }
}
public class OrderLineItemViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
而且,我的实体框架模型如下所示:
public class Order
{
public int Id { get; set; }
/* ... */
public List<OrderLineItem> LineItems { get; set; }
}
public class OrderLineItem
{
public int Id { get; set; }
public string Name { get; set; }
}
我正在努力解决的问题是如何处理编辑现有订单。我的控制器函数会将父视图模型转换为 Order 对象,并将子视图模型 (OrderLineItemViewModel) 转换为实体模型 (OrderLineItem)。但是,将实体附加到 ObjectContext 后,它会丢失已更改、添加或删除的行项目的状态。
我发现的所有解决父/子关系的示例似乎都主张不要对子集合进行级联更新,而是更喜欢使用单独的控制器操作和视图来更新子集合。但是,我试图将编辑作为一个原子操作进行...当用户点击“编辑订单”提交更改时,我希望更新父级的字段,并处理任何新的/删除的/修改的子级。 ..
从视图模型转换时,处理实体框架中子对象的更改跟踪的最佳方法是什么?
我尝试向 ViewModel 和 Model 添加 IsNew、IsDirty 和 IsDeleted,然后为每个子项调用适当的函数(附加、删除或添加),但是在尝试添加时出现错误,提示子项已存在于ObjectStateManager 处于 UnChanged 状态...
谢谢!
I have a ASP.NET MVC 3 application, using Entity Framework 4 to handle Data Access.
My View Model object structure looks like this:
public class OrderViewModel
{
public int Id { get; set; }
/* ... */
public List<OrderLineItemViewModel> LineItems { get; set; }
}
public class OrderLineItemViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
And, my Entity Framework Model looks like this:
public class Order
{
public int Id { get; set; }
/* ... */
public List<OrderLineItem> LineItems { get; set; }
}
public class OrderLineItem
{
public int Id { get; set; }
public string Name { get; set; }
}
The thing that I am struggling with is how to handle editing an existing Order. My controller function will convert the Parent View Model into an Order object, and also convert the children (OrderLineItemViewModel) into the Entity Model (OrderLineItem). However, upon attaching the entity to the ObjectContext, it loses state of which Line Items have been changed, added, or deleted.
All of the examples that I have found that address parent/child relationships seem to advocate not doing cascading updates to children, rather, preferring to have a seperate Controller Action and View for updating the child collection. However, I am trying to have the edit happen as one atomic operation... When the user hits "Edit Order" to submit the changes, I want the parent's fields to update, as well as handle any new/deleted/modified children...
What's the best approach to handling change tracking on child objects in Entity Framework, when converting from a View Model?
I have tried adding a IsNew, IsDirty, and IsDeleted to the ViewModel and the Model, then calling the appropriate function for each child (Attach, Delete or Add), but I get errors when trying to add saying that the child alreadys exists in the ObjectStateManager in an UnChanged state...
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您确实必须以某种方式告诉 EF 哪些内容发生了更改、添加了哪些内容以及删除了哪些内容。有两种方法:
Order
和OrderLines
并将Order
实例附加到上下文。之后,您必须更改每个实体的状态 (
context.ObjectStateManager.ChangeObjectState
)。OrderLines
加载整个Order
,然后将视图模型中的更改合并到附加的实体图 - 这就是我所使用的。更复杂的描述位于另一个答案。当您使用多对多或一对多关系(其中相关实体可以更改父级)时,整个情况会变得更糟。
You must indeed somehow tell EF what has changed, what is added and what is deleted. There are two approaches:
Order
andOrderLines
from your view models andAttach
theOrder
instance to the context. After that you must change state of each entity (context.ObjectStateManager.ChangeObjectState
).Order
withOrderLines
from the database first and then merge changes from view models to attached entity graph - that is what I use.More complex description is in another answer. This whole become much worse when you work with many-to-many or one-to-many relations where related entities can change parent.
只有两种方法可以找出发生了什么变化。
有一种方法可以在不知道发生了什么变化的情况下进行保存,这种方法可能会更有效。但是,它需要创建自定义查询并使用 TSQL 的 MERGE:
http://technet .microsoft.com/en-us/library/bb510625.aspx
There are only two ways to figure out what changed.
There is one way to save without knowing what changed that might be a little more efficient. However, it would require creating a custom query and using TSQL's MERGE:
http://technet.microsoft.com/en-us/library/bb510625.aspx