【问题标题】:Updating object with related entities from detached state从分离状态更新具有相关实体的对象
【发布时间】:2012-04-04 07:26:45
【问题描述】:

当我从实体框架查询时,我总是在分离状态下查询,以便检索到的记录可以存储在缓存中以供后续请求使用。

现在我有一个用户可以编辑的表单,其中包含一个父记录,然后是两个父记录列表。

当数据发布到服务器时,我使用我的视图模型并将它们映射到使用 AutoMapper 的实体框架对象中。数据看起来不错; AutoMapper 正在正确映射数据。

当我附加对象以便更新它时,会引发异常:A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship

public static void UpdateOrder(ShippingOrder shippingOrder) {
    using (OrderEntity orderContext = new OrderEntity()) {
        //Exception happens here
        orderContext.ShippingOrders.Attach(shippingOrder);
        //Update the order itself; mark the order has being modified so the EF will update it.
        orderContext.ObjectStateManager.ChangeObjectState(shippingOrder, System.Data.EntityState.Modified);
        //Perform the update.
        orderContext.SaveChanges();
    }
}

EntityFramework (EF) 似乎认为我的键没有对齐,但我不确定什么是不正确的。外键属性确实有正确的值,所以我不确定它在检查什么。有人有什么想法吗?

【问题讨论】:

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


    【解决方案1】:

    你可以试试这样的:

    ShippingOrder existingShippingOrder = orderContext.ShippingOrders.Find(shippingOrder.ID);
    orderContext.Entry(existingShippingOrder ).CurrentValues.SetValues(shippingOrder);
    

    【讨论】:

      【解决方案2】:

      代替

      orderContext.ObjectStateManager.ChangeObjectState(shippingOrder, System.Data.EntityState.Modified);
      

      试试这个

      orderContext.Entry(ShippingOrder).State = EntityState.Modified;
      

      【讨论】:

      • 我实际上并没有点击该代码。对 Attach 的调用导致异常。
      • @Ek0nomik - 调试时,ShippingOrder 的主键是否为空?我很好奇您是否确保在视图表单中使用@Html.HiddenFor()
      • 我的表中实际上是主键的属性有值。但是,EntityKey 属性(属于 Entity Framework 基类)显示为空值。
      • @Ek0nomik - 这个答案可能对您有所帮助:stackoverflow.com/questions/6015843/…
      • 我已经看过那个问题了。我所有的属性都正确映射。作为外键的属性具有正确的值,并且作为主键的父对象上的属性具有正确的值。我觉得有些基本属性没有正确设置。
      【解决方案3】:

      如解释here

      插入或更新模式 一些应用程序的常见模式是 将实体添加为新实体(导致数据库插入)或附加 实体存在并将其标记为已修改(导致数据库 更新)取决于主键的值。例如,当 使用数据库生成的整数主键来处理 具有零键的实体作为新实体,具有非零键的实体作为 现存的。这种模式可以通过设置实体状态来实现 基于对主键值的检查。例如:

      public void InsertOrUpdate(DbContext context, Unicorn unicorn)
      {
          context.Entry(unicorn).State = unicorn.Id == 0 ?
                                         EntityState.Added :
                                         EntityState.Modified;
          context.SaveChanges();
      }
      

      你可以试试

      public static void UpdateOrder(ShippingOrder shippingOrder) {
          using (OrderEntity orderContext = new OrderEntity()) {       
              orderContext.Entry(shippingOrder).State = shippingOrder.Id==0?
                                                        EntityState.Added :
                                                        EntityState.Modified;
      
              orderContext.SaveChanges();
          }
      }
      

      更新:

      ObjectContext类你可以试试

       public static void UpdateOrder(ShippingOrder shippingOrder) {
              using (OrderEntity orderContext = new OrderEntity()) {                  
                  orderContext.ObjectStateManager.ChangeObjectState(shippingOrder, EntityState.Modified);    
                  orderContext.SaveChanges();
              }
          }
      

      【讨论】:

      • 您使用的是哪个版本的 EF?我的上下文中没有可用的 Entry 方法。
      • 我提到的链接使用DBContext如果你没有进入方法那么你必须使用ObjectContext
      • 更新了答案,这就是您尝试做的,但是将修改后的对象附加到上下文而不将其状态更改为已修改会引发引用完整性异常,因为对象状态未修改,它被视为插入所以发生冲突
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多