【问题标题】:ASP.NET MVC3 Parent-child relationships and Entity Framework, how to update children?ASP.NET MVC3 父子关系和实体框架,如何更新孩子?
【发布时间】:2011-05-19 15:16:54
【问题描述】:

我有一个 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; }
}

我正在努力解决的问题是如何处理编辑现有订单。我的控制器函数会将父视图模型转换为订单对象,并将子视图模型 (OrderLineItemViewModel) 转换为实体模型 (OrderLineItem)。但是,在将实体附加到 ObjectContext 后,它会丢失已更改、添加或删除行项目的状态。

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

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

我尝试将 IsNew、IsDirty 和 IsDeleted 添加到 ViewModel 和 Model,然后为每个孩子调用适当的函数(附加、删除或添加),但在尝试添加时出现错误,说孩子已经以 UnChanged 状态存在于 ObjectStateManager...

谢谢!

【问题讨论】:

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


    【解决方案1】:

    您确实必须以某种方式告诉 EF 发生了什么变化,添加了什么,删除了什么。有两种方法:

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

    更复杂的描述在another answer。当您使用相关实体可以更改父级的多对多或一对多关系时,整个情况会变得更糟。

    【讨论】:

    • 第二种方法的代码示例(尽管使用 DbContext),作为附加参考:stackoverflow.com/q/5538974/270591
    • 谢谢!这验证了我的想法……我曾希望 EF 能够阻止我进行这样的状态管理。
    【解决方案2】:

    只有两种方法可以确定发生了什么变化。

    1. 您可以使用 javascript 在客户端跟踪更改。这意味着当您发布表单时,您的 javascript 会拦截该帖子并将其与加载屏幕时使用的原始数据进行比较。
    2. 您可以遍历子对象并将它们与控制器中的对象进行比较。如果有差异,您可以保存它们。

    有一种在不知道发生了什么变化的情况下进行保存的方法可能更有效。但是,它需要创建自定义查询并使用 TSQL 的 MERGE:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多