Rattacher un graphe d’entités et détecter les modifications de la collection

J’utilise d’abord le code de structure d’entité et expose la firebase database northwind via une interface HTTP WCF REST.

Je n’ai pas exposé la table OrderDetails (éléments de la commande), car il n’est pas logique de créer une commande puis d’append chaque commande requirejse par un autre service. À mon avis, il doit s’agir d’une transaction atomique qui réussit ou échoue. Par conséquent, j’inclus la collection Order.OrderDetails lors de la transmission au client et suppose que j’en obtiendrai lors de la création ou de la mise à jour d’une commande.

Le problème semble toutefois détecter les modifications apscopes à la collection OrderDetails lors du rattachement de l’entité Order à une mise à jour. La commande elle-même peut être définie comme modifiée pour mettre à jour ces propriétés, mais cela ne se répercute pas sur les éléments OrderDetail. Je peux donc manuellement passer en revue et modifier les modifications mises à jour, mais le problème consiste à déterminer celles qui sont mises à jour en premier lieu. Définir un nouveau OrderDetail sur modifié provoquera une erreur lors de la tentative de sauvegarde.

J’ai lu une recommandation visant à définir l’ID des nouveaux éléments de collection sur 0, que le serveur utilise pour décider s’il est nouveau ou existant. Northwind utilise cependant une clé composite entre OrderID et ProductID pour OrderDetails. Ces deux éléments devront être définis par le client, je ne peux donc pas trouver un moyen de détecter les nouveautés. De plus, un OrderDetail supprimé n’existera pas dans le graphe détaché et j’aurai besoin de comprendre ce qui a été supprimé et de le supprimer explicitement.

Tout conseil serait très 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; } 

C’est un problème commun et 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) consistait à charger à nouveau la Order dans votre méthode de mise à jour et à fusionner manuellement les modifications:

 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 également être nécessaire de vérifier manuellement les horodatages si vous les utilisez.

Le scénario alternatif est ce que vous avez décrit, 0 étant utilisé pour les nouveaux détails et un ID négatif pour les détails supprimés, mais c’est la logique qui doit être effectuée sur le client. Cela ne fonctionne également que dans certains cas.

J’ai récemment été autorisé à ouvrir à la source certains travaux que j’ai effectués pour mon employeur il y a quelque temps (avec quelques changements de cap). J’ai en fait écrit une méthode d’extension pour résoudre ce problème, vous pouvez l’obtenir à l’ adresse suivante: http://refactorthis.wordpress.com/2012/12/11/introducing-graphdiff-for-entity-framework-code-first-allowing-automated- mises à jour d’un graphique d’entités détachées /

J’espère que ça aide!