3 votes

Gestion des conflits dans DomainContext

J'ai un service RIA Linq-to-SQL et un client Silverlight. Lorsque deux personnes modifient la même entité, je reçois un EntityConflict dans le OnSubmitCompleted lors de l'appel de SubmitChanges. Je veux seulement lui montrer une boîte de message et lui faire savoir que les données ont été modifiées et que ses modifications seront remplacées par les valeurs du serveur.

MyDomainContext.SubmitChanges(this.OnSubmitCompleted, invokeAfterSubmit);

private void OnSubmitCompleted(SubmitOperation so)
{
 if (so.HasError)
 {
 if (so.EntitiesInError.Any(entity => entity.EntityConflict != null))
  {
  MessageBox.Show("Data has changed, entities will be reloaded....","Error", MessageBoxButton.OK);

  // cache the entities, because the AcceptChanges() will clear them
  var errorEntities = so.EntitiesInError.ToList();

  // overwrite the local changes with the ones from the stoe
  ((IChangeTracking)Context.EntityContainer).AcceptChanges();

  // reload the data
  -> here comes the dirty code from below                  

  // mark as handled as in "The User has been informed that all his stuff has been reverted"
  so.MarkErrorAsHandled();
  }
 }

Je n'ai aucune idée de la façon de recharger les données pour cette entité spécifique. Cela ne me dérangerait même pas de recharger à nouveau toutes ces données.

En ce moment, je fais cela, et je me sens très sale :)

foreach (Entity entity in errorEntities)
  {
   var methodInfo = (from method in Context.GetType().GetMethods()
                     where method.Name.Contains("Query")
                     where method.Name.Contains(entity.GetType().Name)
                                         select method);

   foreach (var info in methodInfo)
     {
     // get the query from the Context to reload the entity
      var result = (EntityQuery) info.Invoke(Context, null);

      // load the entities
       Context.Load(result, LoadBehavior.RefreshCurrent, null, null);
     }

   }

Cela fonctionne, mais je suis sûr qu'il existe de meilleures façons de résoudre les conflits. (Fusionner serait bien sûr génial !)

Veuillez me faire part des meilleures façons de gérer ce scénario :)

4voto

Marco Marczinzik Points 56

Ce problème avec les conflits peut être résolu sur le serveur. Le service de domaine est une classe partielle où vous pouvez surcharger la méthode ResolveConflicts .

Exemple :

protected override bool ResolveConflicts(ChangeConflictCollection conflicts)
{
    bool resolveChangeSetSuccess = true;

    foreach (ObjectChangeConflict objectChangeConflict in conflicts)
    {
        foreach (MemberChangeConflict memberChangeConflict in objectChangeConflict.MemberConflicts)
        {
            if (memberChangeConflict.Member.Name == "Name of DB field")
            {
                memberChangeConflict.Resolve(RefreshMode.KeepCurrentValues);
            }
            else
            {
                memberChangeConflict.Resolve(RefreshMode.KeepChanges);
            }
        }

        resolveChangeSetSuccess = resolveChangeSetSuccess && objectChangeConflict.IsResolved;
    }

    if (resolveChangeSetSuccess)
    {
        this.DataContext.SubmitChanges();
    }

    return resolveChangeSetSuccess;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X