0

我收到以下 InvalidOperationException:

对数据库的更改已成功提交,但在更新对象上下文时出错。ObjectContext 可能处于不一致的状态。内部异常消息:发生引用完整性约束冲突:定义引用约束的属性值在关系中的主体对象和依赖对象之间不一致。

当我运行以下代码时会发生这种情况(注意我在 ShipDates 集合上调用 Clear() 的位置,然后添加新实例):

// get or create the order
Order order = null;
if (vm.OrderNumber > 0)
    order = GetOrder(vm.OrderNumber);
else
    order = new Order(orderDate: DateTime.Now, isClosed: false, brokerNum: broker.BrokerNumber);

// get or create the order page
OrderPage orderPage = null;
bool bIsExistingPage = vm.PageNumber > 0;
if (bIsExistingPage)
    orderPage = order.OrderPages.First(op => op.PageNumber == vm.PageNumber);
else 
    orderPage = new OrderPage(vm.VendorNumber, vm.BulletinNumber, 1, DateTime.Now, order);

// merge changes or create the order page items
foreach (var opi in vm.OrderPageItems)
{
    var orderPageItem = orderPage.OrderPageItems.FirstOrDefault(xopi => 
                                                    xopi.StoreNumber == opi.StoreNumber &&
                                                    xopi.ItemNumber == opi.ItemNumber);
    if (orderPageItem == null)
    {
        orderPageItem = new OrderPageItem(
                                vendorNum: vm.VendorNumber,
                                bullNum: vm.BulletinNumber,
                                itemNum: opi.ItemNumber,
                                storeNum: opi.StoreNumber,
                                quantity: opi.Quantity,
                                orderPage: orderPage);
        orderPage.OrderPageItems.Add(orderPageItem);
    }
    else
    {
        orderPageItem.Quantity = opi.Quantity;
    }
}

// clear out the old ship dates if any
orderPage.ShipDates.Clear();

// reset the ship dates
vm.ShipDates.ForEach(date => orderPage.ShipDates.Add(new OrderPageShipDate(date, orderPage)));

if (!bIsExistingPage)
    order.OrderPages.Add(orderPage);

_context.AddOrUpdate(order);
_context.SaveChanges();

result.OrderNumber = order.OrderNumber;
result.OrderDate = order.OrderDate;

以下是参与识别关系的两个类的相关部分:

/// <summary>
/// This class represents a a set of items added to an order from a particular bulletin at a particular time.
/// </summary>
[ScaffoldTable(true)]
public class OrderPage : IEntity, IAuditInfo
{       
    #region Construction
    //...
    #endregion

    #region IEntity Members
    /// <summary>
    /// The unique identifier for an order item.
    /// </summary>
    [Key]
    public virtual int Id { get; set; }
    #endregion

    // other properties...

    public virtual ICollection<OrderPageShipDate> ShipDates { get; private set; }
}

和:

/// <summary>
/// This class represents a shipping date for an order page that has been added to an order.
/// </summary>
[ScaffoldTable(true)]
public class OrderPageShipDate : IEntity
{
    #region Construction
    // ...
    #endregion

    #region IEntity Members
    /// <summary>
    /// The unique identifier for an order item.
    /// </summary>
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), Column(Order = 2)]
    public virtual int Id { get; set; }
    #endregion

    public virtual DateTime ShipDate { get; private set; }

    [Key, ForeignKey("OrderPage"), Column(Order = 1)]
    public virtual int OrderPageId { get; private set; }

    public virtual OrderPage OrderPage { get; private set; }
}

如果我有一个正在修改的现有 OrderPage,则会在 SaveChanges() 处发生错误。我希望 OrderPage 删除 ShipDates 集合中的所有现有 OrderPageShipDates 并重新添加到新实例中。

你能帮我解决这个问题吗?提前致谢。

哦,请回复下面的回复 - 我在 GetOrder() 调用中明确加载发货日期。这是代码:

[NonAction]
private Order GetOrder(int orderNumber)
{
    var user = _context.Users.SingleOrDefault(u => u.Username == User.Identity.Name);
    var roles = _roleProvider.GetRolesForUser(User.Identity.Name).ToList();

    var broker = user as Broker;
    order = _context.Orders
        .Where(o => o.BrokerNumber == broker.BrokerNumber && o.OrderNumber == orderNumber)
        .Include(o => o.OrderPages)
        .Include(o => o.OrderPages.Select(op => op.OrderPageItems))
        .Include(o => o.OrderPages.Select(op => op.ShipDates))
        .SingleOrDefault();

    return order;
} 
4

1 回答 1

0

Ok, I found the answer or answers.

First, I was trying to do too much before _context.SaveOrUpdate(). I needed to get the Id from the DB for my OrderPage before I added my OrderPageShipDates since their composite keys depend on the 'real' OrderPageId. So I call _context.SaveOrUpdate() before adding them now which gets me the 'real' Id.

Second, I had mis-implemented the _context.AddOrUpdate() logic. It was only doing an Add. Lot's of trickle down effects but the biggest was the Principal Id was changing (it was added again instead of being updated).

Thanks again for your efforts!

于 2013-09-25T15:28:32.053 回答