ASP.NET MVC3亲子关系和实体框架,如何更新子代?

时间:2011-05-19 15:16:55

标签: asp.net-mvc-3 entity-framework-4 viewmodel

我有一个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时,它将丢失已更改,添加或删除行项目的状态。

我发现解决父/子关系的所有示例似乎都主张不对子级进行级联更新,而是更喜欢使用单独的Controller Action和View来更新子集合。但是,我试图将编辑作为一个原子操作发生...当用户点击“编辑顺序”提交更改时,我希望父级的字段更新,以及处理任何新的/删除/修改的子级。 ..

从视图模型转换时,在Entity Framework中处理子对象的更改跟踪的最佳方法是什么?

我已经尝试将IsNew,IsDirty和IsDeleted添加到ViewModel和Model,然后为每个子项调用相应的函数(Attach,Delete或Add),但是在尝试添加说孩子alreadys时我收到错误存在于ObjectStateManager中的UnChanged状态......

谢谢!

2 个答案:

答案 0 :(得分:2)

你必须以某种方式告诉EF什么已经改变,添加什么以及删除什么。有两种方法:

  • 从您的视图模型和Order OrderLines实例创建您的AttachOrder到上下文。之后,您必须更改每个实体的状态(context.ObjectStateManager.ChangeObjectState)。
  • 首先从数据库加载整个Order OrderLines,然后将视图模型中的更改合并到附加的实体图中 - 这就是我使用的。

更复杂的描述在another answer中。当您处理多对多或一对多关系时,这一整体会变得更糟,相关实体可以更改父级。

答案 1 :(得分:0)

只有两种方法可以找出改变了什么。

  1. 您可以使用javascript跟踪客户端的更改。这意味着当您发布表单时,您的javascript将拦截帖子并将其与加载屏幕的原始数据进行比较。
  2. 您可以遍历子对象并将它们与控制器中的对象进行比较。如果存在差异,您可以保存它们。
  3. 有一种方法可以节省而不知道哪些更改可能会更有效率。但是,它需要创建自定义查询并使用TSQL的MERGE:

    http://technet.microsoft.com/en-us/library/bb510625.aspx

相关问题