实体框架,参照完整性约束冲突发生错误从断开区更新实体(Entity framework, refer

2019-09-24 07:48发布

我有以下型号

public class Order
{
    [Key]
    public virtual string OrderNo {get;set;}
    public virtual IList<OrderItem> Items {get;set;}
}

public class OrderItem
{
    [Key]
    public virtual string ItemNo {get; set;}
    public virtual string ParentItemNo {get;set;}
    public virtual string OrderNo {get;set;}

    public virtual OrderItem ParentItem {get;set;}
    public virtual IList<OrderItem> ChildItems {get;set;}
    public virtual IList<ItemProperty> ItemProperties {get;set;}
    public virtual Order Order {get;set;}
}

public class ItemProperty
{
    [Key]
    public virtual string PropertyNo {get; set;}
    public virtual string ParentPropertyNo {get;set;}
    public virtual string OrderItemNo {get;set;}

    public virtual ItemProperty ParentProperty {get;set;}
    public virtual IList<ItemProperty> ChildProperties {get;set;}
    public virtual OrderItem OrderItem {get;set;}
}

我上断开区域运行(与从服务实体框架背景下我们断开)

  1. 我创建了一个订单并保存到数据库

客户:

service.CreateOrder(new Order() { OrderN="fksjdf1" });

服务器:

using(EfDbContext context = new EfDbContext())
{
    context.Orders.Add(order);
    context.SaveChanges();
}
  1. 我需要一个或一个以上的OrderItems添加到以前添加的顺序

客户:

var order = service.GetOrder("fksjdf1");

var item1 = new OrderItem();
item1.ItemNo="i1";
item1.Order=order;
item1.OrderNo=order.OrderNo;
item1.ItemProperties.Add(new ItemProperty()
    PropertyNo="p1",
    OrderItem = item1
})
order.Items.Add(item1);

var item2 = new OrderItem();
item2.ItemNo="i2";
item2.Order=order;
item2.OrderNo=order.OrderNo;
item2.ItemProperties.Add(new ItemProperty()
    PropertyNo="p2",
    OrderItem = item2
});
item2.ItemProperties.Add(new ItemProperty()
    PropertyNo="p3",
    OrderItem = item2
})
order.Items.Add(item2);
service.UpdateOrder(order);

服务器:

using(EfDbContext context = new EfDbContext())
{
    DbEntityEntry dbEntityEntry = context.Entry(order);
    if (dbEntityEntry.State == EntityState.Detached)
    {
        // ERROR
        context.Set<Order>().Attach(order);
    }

    dbEntityEntry.State = EntityState.Modified;
    context.SaveChanges();
}

错误:参照完整性约束冲突发生了:定义引用约束的属性值不本金和依赖对象的关系之间是一致的。

为什么我看到这个错误? 为什么我不能更新此实体?

我如何使用从断开区域实体框架?

编辑1:

public Order GetOrder(string orderNo)
{
using (EfDbContext context = new EfDbContext())
            {
                context.Configuration.ProxyCreationEnabled = false;
                var order = context.Orders
                    .Include(o => o.OrderItems
                                      .Select(z => z.ItemProperties
                                                       .Select(y => y.ChildProperties)))
                                                       .Where(o => o.OrderNo == orderNo)
                    .FirstOrDefault();
            }
}

Answer 1:

你可能有这样的错误,因为你不设置OrderItemNoItemProperty ,就像这样:

var item1 = new OrderItem();
item1.ItemNo="i1";
item1.Order=order;
item1.OrderNo=order.OrderNo;
item1.ItemProperties.Add(new ItemProperty {
    PropertyNo="p1",
    OrderItem = item1,
    OrderItemNo = item1.ItemNo // = "i1"
});
order.Items.Add(item1);

// and the same for item2

当订单被附加到上下文,相关命令的项目和项目属性得到重视,以及。 导航性能OrderItemItemProperty指的是实体与您提供的密钥( "i1" ),但外键OrderItemNo没有该键值。 这就是异常抱怨不一致。

编辑

不幸的是它不是那么容易更新数据库中分离对象图。 设置一个实体的状态Modified只有标记为这个实体Modified并没有相关的实体。

GetOrder方法使事情变得复杂,因为你急切地装入现有的项目和更多的相关的东西给客户,然后再添加新的OrderItem在客户端S和发送该新修改的对象图回服务器。 在服务器端,您现在有,你必须以不同的处理已经存在的项目(不将它们插入到数据库),比新项目的问题(把它们插入到数据库中)。 要做到这一点,你需要检测哪些项目是旧的,哪些是新的。 如果你没有在实体本身将表明,如果实体是新的或不运输某些标志,你必须再次查询数据库,比较从数据库中装载了从客户端发送分离对象图的对象图。 一般的草图如何可以做到的是在这里: https://stackoverflow.com/a/5540956/270591 。(这仅适用于子集父母如果孙子藏品参与-就像在你的模型-它变得越来越复杂。)

在我看来,你可以简化整个过程,如果你不仅会这一全球service.UpdateOrder(order) ,试图处理对象图中所有可能的变化,而且是利用您对变化的知识,一些专门的方法的方法曲线图-在这种情况下,用于将新的专用方法OrderItem现有的订单秒。 它看起来是这样的:

var order = service.GetOrder("fksjdf1");

var newOrderItems = new List<OrderItem>();

var item1 = new OrderItem();
item1.ItemNo="i1";
item1.OrderNo=order.OrderNo; // leave the Order property null
item1.ItemProperties.Add(new ItemProperty { PropertyNo="p1" });
newOrderItems.Add(item1);

// the same for item2
newOrderItems.Add(item2);

service.AddNewOrderItems(newOrderItems);

而服务的方法是:

public void AddNewOrderItems(List<OrderItem> newOrderItems)
{
    using(EfDbContext context = new EfDbContext())
    {
        foreach (var newOrderItem in newOrderItems)
            context.Set<OrderItem>().Add(newOrderItem);

        context.SaveChanges();
    }
}


文章来源: Entity framework, referential integrity constraint violation occurred error on updating entity from disconnected area