在单元测试中,我尝试测试订单项目的更新/删除/插入。它是订单和订单项之间的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;
}
}