EF5如何通过添加新子项来更新父级

时间:2015-02-11 19:52:27

标签: c# entity-framework unit-testing

在单元测试中,我尝试测试订单项目的更新/删除/插入。它是订单和订单项之间的1到N关系。

当我尝试将新子项添加到控制器更新代码中的现有父项时,我一直收到DBUpdateConcurrencyException。

这是一个例外:存储更新,插入或删除语句影响了意外的行数(0)。自实体加载后,实体可能已被修改或删除。刷新ObjectStateManager条目。

我的问题是: a)将新项目添加到现有父项的正确方法是什么? a)将项目删除到现有父项的正确方法是什么? b)如果没有,从异常消息中,如何更新Objectstatemanager条目?

型号代码:

public class Order
{
    [Key]
    public int OrderID { get; set; }
    ...
    public virtual ICollection<OrderItem> lstOrderItems { get; set; }

    public Order()
    {
        OrderID = 0;
        ...
        lstOrderItems = new List<OrderItem>();
    }
}

public class OrderItem
{
    [Key, Column(Order = 0)]
    public int? OrderID { get; set; }

    [Key, Column(Order = 1)]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int OrderItemID { get; set; }

    [ForeignKey("OrderID")]
    public virtual Order Orders { get; set; }

    public OrderItem()
    {
        OrderID = 0;
        OrderItemID = 0;
        Orders = new Order();
    }
}

单位测试,用于填充订单和订单商品 注意:我之前已成功将商品添加到此订单,没有例外。这个单元测试测试在这个订单中添加了一个新的orderitem(第4项),以及我获得异常的地方。

     Order oOrder = new Order();
        oOrder.OrderID = TEST_ORDERID;


        OrderItem oItems = new OrderItem();

        #region Add items
        oItems.OrderID = 1;
        oItems.OrderItemID = 1;
        oItems.Orders = oOrder;

        oOrder.lstOrderItems.Add(oItems);

        oItems = new OrderItem();
        oItems.OrderID = 1;
        oItems.OrderItemID = 2;
        oItems.Orders = oOrder;           

        oOrder.lstOrderItems.Add(oItems);

        oItems = new OrderItem();
        oItems.OrderID = 1;
        oItems.OrderItemID = 3;
        oItems.Orders = oOrder;

        oOrder.lstOrderItems.Add(oItems);

        / *** This is the new item ***/
        oItems = new OrderItem();
        oItems.OrderID = 0;
        oItems.OrderItemID = 1000;     // Constant that identifies this is a new orderitem
        oItems.Orders = oOrder;

        oOrder.lstOrderItems.Add(oItems);

生成例外的控制器代码:

public void Update(Order o)
    {
        OrderContext _context = new OrderContext();  // Where OrderContext is derived from DBContext
        try
        {
            bool bAdded = false;

            foreach (var i in o.lstOrderItems)
            {
                i.OrderID = o.OrderID;
            }

            foreach (var i in o.lstOrderItems)
            {
                if (i.OrderItemID == 1000)
                {
                    if (i.Qty > 0)
                    {
                        _context.Entry(i).State = System.Data.EntityState.Added;
                        i.OrderItemID = 0;  // Not sure if I have to reset this back to 0
                    }
                    else
                    {
                        _context.Entry(i).State = System.Data.EntityState.Deleted;
                    }
                }
                else
                {

                    if (i.OrderItemID != -1000)
                    {
                        if (i.Qty > 0)
                        {
                            _context.Entry(i).State = System.Data.EntityState.Modified;
                        }
                        else
                        {
                            _context.Entry(i).State = System.Data.EntityState.Deleted;
                        }
                    }
                    else
                    {
                        _context.Entry(i).State = System.Data.EntityState.Deleted;
                    }
                }
            }

            _context.Entry(o).State = System.Data.EntityState.Modified; 

            _context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            var objContext = ((IObjectContextAdapter)_context).ObjectContext;
            objContext.Refresh(System.Data.Objects.RefreshMode.ClientWins, _context.Orders);

            objContext.SaveChanges();    // WHen this line executes, it generates a OptimisticConcurrencyException.
        }
        catch (Exception e)
        {
            throw;
        }
    }

0 个答案:

没有答案