簡體   English   中英

操作失敗:由於一個或多個外鍵屬性不可為空,因此無法更改該關系。

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM