2016-06-29 41 views
1

此問題可能看起來像其他類似問題的重複。但是,我建議你直到最後閱讀問題,然後決定它是否重複某個帖子或不是?操作失敗:由於一個或多個外鍵屬性不可空,因此無法更改關係。

我在我的數據庫6張桌子如下:

enter image description here

我已經插入所有表中的一些記錄。

現在,我正在嘗試更新訂單。

起初,我只是想更新的順序如下:

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; 
    } 
} 

在這一點上,我得到了一個錯誤說:

Multiplicity constraint violated. The role '…' of the relationship '…' has multiplicity 1 or 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(); 
} 

現在,我得到另一個錯誤,說:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

我得到下面提到線這個錯誤在最後的代碼塊:

DispatchClient.DeleteDispatch(dispatch); 

回答

1

你有兩個不同的問題。我們沒有足夠的細節給你一個具體的修復,但是因爲這些都是非常常見的EF「陷阱」,所以我認爲這對於解決發生的事情是很有價值的。

第一個錯誤:

Multiplicity constraint violated. The role '…' of the relationship '…' has multiplicity 1 or 0..1

這意味着您的外鍵的屬性不匹配。在EF中,您經常會在模型中以多種方式表示相同的SQL關係。

例如,您的Order類可能有一個OrderItemDetails集合(它使用OrderItemDetail.OrderId填充)。您的OrderItemDetail也可能有一個Order屬性,它使用相同的外鍵填充。如果這兩個屬性都標記爲已更改但新值不匹配,則EF不知道將什麼新值保存到OrderItemdetail.OrderId字段。在這種情況下,它會拋出這個例外。如果OrderItemDetail具有Order屬性和OrderId屬性,則會發生同樣的問題。

爲了避免這個問題,你必須非常小心你修改的屬性。使用屬性映射器可能是危險的,因爲它們可能會「意外」修改錯誤的屬性並導致諸如此類的許多問題。我們需要了解SimpleMapper的工作方式或配置如何配置真正的故障排除。

第二個錯誤:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

此錯誤通常意味着你並沒有真正刪除對象。您將從關係集合中刪除該對象,該關係集合只將外鍵設置爲null。

繼續上面的例子,如果你調用myOrder.OrderItemDetails.Remove(detail)然後調用SaveChanges,你可能會認爲它會從數據庫中刪除OrderItemDetail記錄,但這不是你要求的。您將其從與 myOrder相關的訂單商品明細中刪除。爲了實現這一點,EF生成一個UPDATE語句,將OrderId列設置爲null。如果沒有關於您的模型和DeleteDispatch方法中的代碼的更多詳細信息,很難確切地知道問題出在哪裏,但意外意味着它試圖將該外鍵屬性設置爲空和失敗,因爲它是不可空的。

「修復」是直接從上下文集合中刪除項目,而不是相關項目集合。即而不是myOrder.OrderItemDetails.Remove,你應該調用context.OrderItemDetails.Remove。這會刪除真實的記錄。

+0

謝謝你的一個很好的解釋。我已經得到了我的答案。 – Vishal

相關問題