![](/img/trans.png)
[英]The relationship could not be changed because one or more of the foreign-key properties is non-nullable. (2)
[英]The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable.
這個問題可能看起來像其他類似問題的重復。 但我建議您仔細閱讀問題,然后再決定是否與某些帖子重復????
我的數據庫中有6個表,如下所示:
我已經在所有表中插入了一些記錄。
現在,我正在嘗試更新訂單。
起初,我只是嘗試如下更新訂單:
CurrentOrder.UpdateOrder(Order);
OrderClient中的UpdateOrder方法如下所示:
public Order UpdateOrder(Order Order)
{
IOrderRepository OrderRepository = _DataRepositoryFactory.GetDataRepository<IOrderRepository>();
Order updatedEntity = null;
if (Order.OrderId == 0)
{
updatedEntity = OrderRepository.Add(Order);
}
else
{
updatedEntity = OrderRepository.Update(Order);
}
return updatedEntity;
}
並在OrderRepository中:
protected override Order UpdateEntity(RateDifferenceContext entityContext, Order entity)
{
return (from e in entityContext.OrderSet
where e.OrderId == entity.OrderId
select e).FirstOrDefault();
}
然后在DataRepositoryBase類中,我使用以下方法:
public T Update(T entity)
{
using (U entityContext = new U())
{
T existingEntity = UpdateEntity(entityContext, entity);
SimpleMapper.PropertyMap(entity, existingEntity);
entityContext.SaveChanges();
return existingEntity;
}
}
這時我出現了一個錯誤,說:
違反多重性約束。 關系“ ...”的角色“ ...”具有多重性1或0..1
因此,我認為我需要刪除所有相關表中特定於該順序的記錄。 因此,我嘗試了以下代碼:
using (var xaction = new TransactionScope())
{
foreach (OrderItemDetail orderItemDetail in OrderItemDetailClient.GetAllOrderItemDetails().Where(x => x.OrderId == NewOrder.OrderId))
{
OrderItemDetailClient.DeleteOrderItemDetail(orderItemDetail);
}
foreach (Dispatch dispatch in DispatchClient.GetAllDispatches().Where(x => x.OrderId == NewOrder.OrderId))
{
foreach (DispatchItemDetail dispatchItemDetail in DispatchItemDetailClient.GetAllDispatchItemDetails().Where(x => x.InvoiceId == dispatch.InvoiceId))
{
DispatchItemDetailClient.DeleteDispatchItemDetail(dispatchItemDetail);
}
DispatchClient.DeleteDispatch(dispatch);
}
OrderClient.UpdateOrder(NewOrder);
xaction.Complete();
}
現在,我收到另一個錯誤消息:
操作失敗:由於一個或多個外鍵屬性不可為空,因此無法更改該關系。 對關系進行更改時,相關的外鍵屬性將設置為空值。 如果外鍵不支持空值,則必須定義新的關系,必須為外鍵屬性分配另一個非空值,或者必須刪除不相關的對象。
我在最后一個代碼塊的以下提到的行中收到此錯誤:
DispatchClient.DeleteDispatch(dispatch);
您有兩個不同的問題。 我們沒有足夠的細節來為您提供特定的修復程序,但是由於它們都是非常常見的EF“陷阱”,因此我相信逐步了解正在發生的事情非常有價值。
第一個錯誤:
違反多重性約束。 關系“ ...”的角色“ ...”具有多重性1或0..1
這意味着您的外鍵屬性不匹配。 在EF中,您通常會遇到在模型中以多種方式表示相同的SQL關系的情況。
例如,您的Order類上可能有一個OrderItemDetails集合(使用OrderItemDetail.OrderId填充)。 您的OrderItemDetail可能還具有Order屬性,該屬性使用相同的外鍵填充。 如果這兩個屬性都標記為已更改,但新值不匹配,則EF不知道要保存到OrderItemdetail.OrderId字段中的新值。 在這種情況下,它將拋出此異常。 如果OrderItemDetail具有Order屬性和OrderId屬性,則會發生相同的問題。
為避免此問題,您必須非常小心修改哪些屬性。 使用屬性映射器可能很危險,因為它們會“意外地”修改錯誤的屬性,並引起許多此類問題。 我們將需要查看SimpleMapper的工作方式或將該映射配置為真正的故障排除方法。
第二個錯誤:
操作失敗:由於一個或多個外鍵屬性不可為空,因此無法更改該關系。 對關系進行更改時,相關的外鍵屬性將設置為空值。 如果外鍵不支持空值,則必須定義新的關系,必須為外鍵屬性分配另一個非空值,或者必須刪除不相關的對象。
此錯誤通常表示您並未真正刪除對象。 您正在從關系集合中刪除對象,該關系集合僅將外鍵設置為null。
繼續上面的示例,如果您調用myOrder.OrderItemDetails.Remove(detail)然后調用SaveChanges,您可能會認為它只會從數據庫中刪除OrderItemDetail記錄,但這並不是您真正要的。 您從與 myOrder 關聯的訂單商品詳細信息列表中將其刪除。 為此,EF生成了UPDATE語句,該語句將OrderId列設置為null。 如果沒有來自DeleteDispatch方法的有關模型和代碼的更多詳細信息,很難確切地知道問題出在哪里,但是異常意味着它試圖將外鍵屬性設置為null並失敗,因為它是不可為空的。
“修復”是直接從Context集合而不是相關的項目集合中刪除項目。 即,而不是myOrder.OrderItemDetails.Remove,應調用context.OrderItemDetails.Remove。 這將刪除真實記錄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.