Frage

Ich verwende zuerst den Entity Framework -Code und enthülle die Northwind -Datenbank über eine WCF -REST -HTTP -Schnittstelle.

Ich habe die Bestelldetail -Tabelle (Bestellelemente) nicht aufgedeckt, da sie keinen Sinn erstellen und dann jeden erforderlichen Auftragsdetail durch einen anderen Service separat hinzugefügt haben. Meiner Meinung nach muss es eine atomare Transaktion sein, die entweder erfolgreich ist oder als eine fehlschlägt. Daher füge ich die Auftrag ein. OrderDetails Sammlung beim Übergeben an den Kunden und gehe davon aus, dass ich eine erhalten werde, wenn eine Bestellung erstellt oder aktualisiert wird.

Das Problem scheint jedoch die Erkennung von Änderungen der Auftragsdetail -Sammlung zu erkennen, wenn die Bestellentität für ein Update wieder aufgenommen wird. Die Bestellung selbst kann so geändert werden, dass diese Eigenschaften aktualisiert werden. Dies ist jedoch nicht auf die OrderDetail -Elemente. So kann ich manuell durch die modifizierten aktualisierten und einstellen, aber das Problem liegt darin, herauszufinden, welche überhaupt aktualisiert werden. Das Einstellen eines neuen OrderDetails in modifiziertes Einstellen führt zu einem Fehler beim Speichern.

Ich habe eine Empfehlung gelesen, um die ID neuer Sammlungselemente auf 0 festzulegen, und verwenden Sie diese auf dem Server, um zu entscheiden, ob sie neu oder vorhanden ist. Northwind verwendet jedoch einen zusammengesetzten Schlüssel zwischen Orderid und ProductID für OrderDetails. Diese müssen beide vom Kunden festgelegt werden, daher kann ich keinen Weg finden, um zu erkennen, was neu ist. Darüber hinaus gibt es im abgelösten Diagramm keine gelöschte Auftragsdetails und ich muss herausfinden, was gelöscht wurde, und es explizit entfernen.

Jeder Rat wäre sehr geschätzt.

public override Order Update(Order entity)
{
    dbset.Attach(entity);
    DataContext.Entry(entity).State = EntityState.Modified;

    foreach (var orderDetail in entity.OrderDetails)
    {
        DataContext.Entry(orderDetail).State = EntityState.Modified;
    }

    return entity;
}
War es hilfreich?

Lösung

Das ist Gemeinsames und komplexes Problem Und es gibt keine Magie, die es für Sie tun wird. Meine Lösung (und die einzige, die in allen Szenarien funktioniert) war, das zu laden Order Wiederum in Ihrer Update -Methode und fusionieren Sie manuell Änderungen:

public override Order Update(Order entity)
{
    // No attach of entity

    var attached = DataContext.Orders.Include(o => o.OrderDetails).SingleOrDefault(...);
    if (attached == null) ...

    // Merge changes from entity to attached - if you change any property
    // it will be marked as modified automatically

    foreach (var detail in attached.OrderDetails.ToList())
    {
        // ToList is necessary because you will remove details from the collection

        // if detail exists in entity check if it must be updated and set its state

        // if detail doesn't exists in entity remove if from collection - if it is \
        // aggregation (detail cannot exists without Order) you must also delete it 
        // from context to ensure it will be deleted from the database
    }

    foreach (var detail in entity.OrderDetails)
    {
        // if it doesn't exists in attached create new detail instance,
        // fill it from detail in entity and add it to attached entity - 
        //you must not use the same instance you got from the entity
    }

    DataContext.SaveChanges();

    return entity;
}

Es muss auch die Zeitstempel manuell überprüfen, wenn Sie sie verwenden.

Alternatives Szenario ist das, was Sie mit 0 beschrieben haben, die für neue Details und negative IDs für gelöschte Details verwendet werden, aber das ist Logik, die auf dem Client erfolgen muss. Es funktioniert auch nur in einigen Fällen.

Andere Tipps

Ich hatte vor einiger Zeit vor einiger Zeit Open -Source -Arbeiten, die ich für meinen Arbeitgeber geleistet habe (natürlich mit einigen Änderungen). Ich habe tatsächlich eine Erweiterungsmethode geschrieben, um dieses Problem zu lösen. Sie können sie erhalten http://refactorthis.wordpress.com/2012/12/11/introducing-graphdiff-for-entity-framework-code-first-alowing-automated-updates-of-a-graph-ofdached-entities/

Ich hoffe es hilft!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top