9
votes

Dbcontext et rejetchanges

Je travaillais avec des services RIA où ObjectContext a la méthode de RejectChanges (). Cependant, je travaille maintenant avec EF 4.4 dans une application de bureau et je ne trouve pas cette méthode. Donc, ma question est la suivante: dans un scénario où je permet à l'utilisateur de faire des opérations de crud par lots sur la collecte, comment puis-je revenir tous les changements? Je pourrais aller avec recréer le contexte et récupérer les données à nouveau, mais cela sonne très inutile si je dois revenir à des modifications à 1-2 entités.

Alors, quelle est la meilleure façon de rejeter les changements? Et aussi, comment savons-nous si le contexte fait quelque chose (isbusy)?


0 commentaires

5 Réponses :


12
votes

ef n'a pas d'opération directe de "modifications de rejet". Vous pouvez passer via des entrées d'entité dans Changetracker / ObjectStaTeManager et écrase les valeurs actuelles avec des valeurs d'origine pour des entités modifiées. Vous pouvez également détacher des entités ajoutées et modifier des entités supprimées à l'inchangage mais que tout ne fonctionnera que si vous (ou EF en interne) n'a pas changé l'état d'une association indépendante (relation). Si vous travaillez avec des relations aussi, le tout peut devenir beaucoup plus compliqué, car vous devez également revenir à des relations - dans ce cas, il est plus simple de recharger des données.

Pour revenir à des modifications de DBContext API, vous pouvez essayer ceci: xxx

Dans ce cas, je pense que le problème principal est la façon dont vous travaillez avec des entités - vous autorisez les modifications sur Données en direct et EF fait sa logique sur le dos pour conserver des données cohérentes lorsque des modifications sont effectuées, mais plus tard, vous décidez que ces modifications ne seront pas enregistrées. Dans ce cas, vous devriez faire l'une des opérations suivantes:

  • Jeter les données modifiées et recharger le jeu de données entiers (en recréant le contexte)
  • Séparez cette logique pour ne pas fonctionner sur des données en direct et poussez la modification des données au contexte EF uniquement lorsque la modification est vraiment confirmée

    Le contexte fait quelque chose si vous le dites à faire quelque chose. Il ne devient jamais occupé lui-même.


3 commentaires

Recréer le contexte serait une solution fine. Cependant, j'ai eu des problèmes de synchronisation des données connexes. Un exemple serait que j'avais crud sur Collectiona sur la vie et CRUD sur CollectionB sur ViewB. Collectionb contient également une référence à Collectiona. Donc, si j'ai 2 objets de contexte, à la fois pour Collectiona et Collectionb, comment puis-je synchroniser Viewb, si je change de collection sur la vie? Lorsque vous avez un contexte, tout est synchronisé, puisque nous ne travaillons réellement sur une seule instance Collectiona, pas deux. Recréer un contexte «global» créerait un gâchis. :) Est-ce que j'ai commis une erreur en utilisant un contexte "global"?


En ce qui concerne le "occupé", j'étais inquiet de ce qui se passera si j'abandonnais une charge dans l'async manoir, puis j'essaie d'émettre une autre charge, tout en ne terminant pas? De cette façon, je pouvais vérifier si c'est "occupé", alors je pourrais faire la queue une nouvelle charge.


+1 pour remarquer ce que la plupart des gens semblent manquer Re. Les relations: il est possible d'avoir suivi des changements qui ne seront pas ramassés simplement en regardant à travers la collection d'entrées pour l'état! = inchangé. (Ef v6.)



1
votes

Cela fonctionne pour moi: xxx

ceci = dbcontext dans ce cas


1 commentaires

Qu'en est-il des entités supprimées? En outre, comment obtiendriez-vous de nouvelles données pour les entités modifiées par d'autres utilisateurs, pas vous?



2
votes

Je sais que c'est une ancienne question. Cependant, aucune des réponses ne correspond à ma situation. Je devais rejeter les changements sur une seule entité dans une collection. C'est ce qui a fonctionné pour moi: xxx


3 commentaires

Bien que la question portait sur les changements de collecte, pas une entité unique, je ne vois pas comment aucune des réponses ne vous a aidé? La réponse juste au-dessus de la vôtre (Thesoul75) est exactement la même que celle que vous êtes la suggestion, seulement il le fait pour tous les articles de la collection.


Goran, si tous les changements de la collection ont été rejetés, mes données seront invalides. Un seul des éléments de la collection doit revenir aux valeurs d'origine. J'ai besoin d'une approche plus granulaire. Je sais parfois que d'autres ont besoin de contrôle granulaire également. J'ai posté la réponse pour aider les autres ayant des exigences similaires.


Eh bien, vous n'utilisez pas de nourriture, mais vous utilisez essentiellement le même technique (rafraîchir avec des magasins), donc je ne vois donc pas la valeur ajoutée de votre réponse, car vous venez de supprimer la boucle.



11
votes
public void RejectChanges()
        {
            foreach (var entry in ChangeTracker.Entries())
            {
                switch (entry.State)
                {
                    case EntityState.Modified:
                        {
                            entry.CurrentValues.SetValues(entry.OriginalValues);
                            entry.State = EntityState.Unchanged;
                            break;
                        }
                    case EntityState.Deleted:
                        {
                            entry.State = EntityState.Unchanged;
                            break;
                        }
                    case EntityState.Added:
                        {
                            entry.State = EntityState.Detached;
                            break;
                        }
                }
            }
        }

2 commentaires

Cela semble être la seule réponse qui gère tous les états sans frapper la base de données. +1


Et si je n'ai changé que des références? Particulièrement pure m: n quand il n'y a pas de propriété de clé étrangère touchée?



0
votes

Cela peut être une vieille réponse mais utile à tous les nouveaux visiteurs .... La fonction de rechargement rechargera l'objet de la source de données et écrasera les modifications existantes et l'entité nouvellement chargée aura un statut inchangé.

public static void UndoEntityChanges(object Entity)
{
    <EFModelContainer>.Entry(Entity).Reload();
}


0 commentaires