2016-06-29 14 views
1

Diese Frage könnte wie ein Duplikat zu anderen ähnlichen Fragen aussehen. Aber ich schlage dir vor, die Frage bis zum Ende zu lesen und dann zu entscheiden, ob es ein Duplikat von irgendeinem Beitrag ist oder nicht ?????Der Vorgang ist fehlgeschlagen: Die Beziehung konnte nicht geändert werden, da mindestens eine Eigenschaft des Fremdschlüssels nicht nullfähig ist.

Ich habe 6 Tabellen in meiner Datenbank wie folgt:

enter image description here

ich einige Datensätze haben bereits in allen Tabellen eingefügt.

Jetzt versuche ich eine Bestellung zu aktualisieren.

Zuerst habe ich versucht, einfach zu aktualisieren, wie folgt:

CurrentOrder.UpdateOrder(Order); 

Die UpdateOrder Methode in OrderClient wie folgt aussieht:

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; 

} 

Und in OrderRepository:

protected override Order UpdateEntity(RateDifferenceContext entityContext, Order entity) 
{ 
    return (from e in entityContext.OrderSet 
      where e.OrderId == entity.OrderId 
      select e).FirstOrDefault(); 
} 

Und dann verwende ich in der Klasse DataRepositoryBase die folgende Methode:

public T Update(T entity) 
{ 
    using (U entityContext = new U()) 
    { 
     T existingEntity = UpdateEntity(entityContext, entity); 
     SimpleMapper.PropertyMap(entity, existingEntity); 
     entityContext.SaveChanges(); 
     return existingEntity; 
    } 
} 

An dieser Stelle habe ich eine Fehlermeldung,:

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

So, dachte ich, dass ich die Aufzeichnungen löschen muß, die in allen verknüpften Tabellen zu dieser Reihenfolge spezifisch sind. Also versuchte ich den Code unten:

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

Nun bekomme ich eine andere Fehlermeldung, dass:

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.

ich diesen Fehler auf unten genannten Zeile in der letzten Codeblock:

DispatchClient.DeleteDispatch(dispatch); 

Antwort

1

Sie haben zwei verschiedene Probleme. Wir haben nicht genug Details, um Ihnen eine spezifische Lösung zu geben, aber da dies beides sehr häufige EF "Gotchas" sind, glaube ich, dass es wertvoll ist, durchzugehen, was passiert.

Der erste Fehler:

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

Dies bedeutet, dass Ihre Fremdschlüssel Eigenschaften nicht übereinstimmen. In EF landen Sie häufig in Situationen, in denen dieselbe SQL-Beziehung in Ihrem Modell mehrfach vertreten ist.

Zum Beispiel kann Ihre Order-Klasse eine Sammlung von OrderItemDetails enthalten (die mit OrderItemDetail.OrderId gefüllt wird). Ihre OrderItemDetail kann auch eine Order-Eigenschaft enthalten, die mit demselben Fremdschlüssel gefüllt wird. Wenn diese beiden Eigenschaften als geändert markiert sind, die neuen Werte jedoch nicht übereinstimmen, weiß EF nicht, welchen neuen Wert das Feld "OrderItemdetail.OrderId" speichern soll. In dieser Situation wird diese Ausnahme ausgelöst. Das gleiche Problem kann auftreten, wenn OrderItemDetail über eine Order-Eigenschaft und eine OrderId-Eigenschaft verfügt.

Um dieses Problem zu vermeiden, müssen Sie sehr vorsichtig sein, welche Eigenschaften Sie ändern.Die Verwendung von Eigenschaften-Mappern kann gefährlich sein, da sie "versehentlich" die falschen Eigenschaften modifizieren und viele Probleme verursachen können. Wir müssten sehen, wie SimpleMapper funktioniert oder wie das Mapping konfiguriert ist, um wirklich Fehler zu beheben.

Der zweite Fehler:

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.

Dieser Fehler bedeutet normalerweise, dass Sie nicht wirklich ein Objekt löschen. Sie entfernen das Objekt aus einer Beziehungssammlung, die den Fremdschlüssel nur auf null setzt. Wenn Sie mit dem obigen Beispiel fortfahren, rufen Sie myOrder.OrderItemDetails.Remove (detail) auf und rufen dann SaveChanges auf, und Sie denken vielleicht, dass es nur den OrderItemDetail-Datensatz aus der Datenbank löscht, aber das ist nicht das, was Sie ihm gesagt haben. Sie haben es aus der Liste der Bestellpositionsdetails entfernt, die mit myOrder verknüpft sind. Um dies zu erreichen, erzeugt EF eine UPDATE-Anweisung, die die OrderId-Spalte auf null setzt. Ohne weitere Details zu Ihrem Modell und Code aus Ihrer DeleteDispatch-Methode ist es schwierig, genau zu wissen, wo das Problem liegt. Die Ausnahme bedeutet jedoch, dass diese Fremdschlüsseleigenschaft auf null gesetzt wird und fehlschlägt, weil sie nicht nullfähig ist.

Die "Lösung" ist das Entfernen von Elementen direkt aus der Context-Auflistung anstelle der zugehörigen Elementauflistung. I.e. anstelle von myOrder.OrderItemDetails.Remove sollten Sie context.OrderItemDetails.Remove aufrufen. Dies löscht den Datensatz für echt.

+0

Vielen Dank für eine großartige Erklärung. Ich habe meine Antwort. – Vishal

Verwandte Themen