Я получаю следующее InvalidOperationException:Entity Framework 5 Определения отношений с помощью Code First бросков InvalidOperationException
Изменения в базу данных были совершенно успешно, но произошла ошибка при обновлении контекста объекта. Объект ObjectContext может находиться в несогласованном состоянии. Внутреннее сообщение об исключении: произошло нарушение ограничения ссылочной целостности: значения свойств, которые определяют ссылочные ограничения, несовместимы между главными и зависимыми объектами в отношении.
Это происходит, когда я запускаю следующий код (обратите внимание, где я называю Clear() на коллекции ShipDates, а затем добавить новые экземпляры):
// 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; }
}
Ошибка возникает при SaveChanges(), если у меня есть существующая OrderPage, которую я изменяю. Я хочу, чтобы OrderPage удалял все существующие OrderPageShipDates в коллекции ShipDates и добавлял их обратно в новые экземпляры.
Можете ли вы помочь мне понять это? Заранее спасибо.
О, ответ ниже: я явно загружаю даты отправки в вызове 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;
}
Я ожидаю, что явная загрузка «orderPage.ShipDates» перед их очисткой решит проблему, но ваш код имеет несколько путей выполнения, поэтому трудно сказать. –
Я явно загружаю их в вызов GetOrder(). Вот этот код: – jlavallet
Если кто-то еще может мне помочь, обратите внимание, что я добавил код в конце моего исходного сообщения. Благодарю. – jlavallet