Question

J'utilise le code-cadre de l'entité première et d'exposer la base de données Northwind via une interface HTTP REST WCF.

Je n'ai pas exposé la table OrderDetails (articles de commande) car il n'a pas de sens la création d'un ordre, puis en ajoutant chaque séparement OrderDetail requis par un autre service. A mon avis, il doit être une transaction atomique qui soit réussit ou échoue comme l'un. Par conséquent, j'inclure la collection Order.OrderDetails lors du passage au client et suppose que je vais obtenir un lorsqu'une commande est créé ou mis à jour.

Le problème semble toutefois détecter des modifications à la collection OrderDetails lorsque l'entité refixer de commande pour une mise à jour. L'ordre lui-même peut être défini comme modifié pour mettre à jour ces propriétés, mais cela ne veut pas en cascade aux éléments de OrderDetail. Je peux donc effectuer manuellement et ensemble les mises à jour à modifiés, mais les mensonges de problème en déterminer quels sont ceux qui sont mis à jour en premier lieu. Définition d'une nouvelle OrderDetail à modifier provoquera une erreur en essayant de sauver.

J'ai lu une recommandation pour définir l'ID de nouveaux objets de collection à 0 et dans l'utilisation du serveur pour décider si elle est nouvelle ou existante. Northwind utilise cependant une clé composite entre OrderID et ProductID pour OrderDetails. Ceux-ci devront tous deux être fixé par le client, je ne peux pas trouver un moyen de détecter ce qui est nouveau. En outre, une supprimé OrderDetail n'existera pas dans le graphique détaché et je besoin de savoir ce qui a été supprimé et supprimer explicitement.

Tout conseil serait apprécié.

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;
}
Était-ce utile?

La solution

est et question complexe et il n'y a pas de magie qui le fera pour vous. Ma solution (et la seule qui fonctionne dans tous les scénarios) a été de charger à nouveau la Order dans votre méthode de mise à jour et fusionner les modifications manuellement:

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

Il peut être aussi besoin de vérifier manuellement horodatages si vous les utilisez.

Scénario alternatif est ce que vous avez décrit avec 0 utilisé pour de nouveaux détails et ID négatif pour les détails supprimés mais c'est la logique qui doit être fait sur le client. Il fonctionne aussi que dans certains cas.

Autres conseils

Je l'ai récemment été autorisé à open source un travail que je l'ai fait pour mon employeur il y a un certain temps (avec quelques changements de cap). Je l'ai écrit en fait une méthode d'extension pour résoudre ce problème, vous pouvez l'obtenir à http://refactorthis.wordpress.com/2012/12/11/introducing-graphdiff-for-entity-framework-code-first -permettant-de-un-détaché-graphe-de-mises à jour automatiques-entités /

it helps!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top