Обработка конфликтов в DomainContext - PullRequest
3 голосов
/ 18 апреля 2011

У меня есть служба RIA Linq-to-SQL и клиент Silverlight. Когда 2 человека редактируют одну и ту же сущность, я получаю EntityConflict в OnSubmitCompleted при вызове SubmitChanges. Теперь я хочу реагировать на это, не слишком раздражая пользователя, я только хочу показать ему окно сообщения и сообщить ему, что данные были изменены и что его изменения будут переопределены значениями сервера.

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

Я понятия не имею, как перезагрузить данные для этого конкретного объекта. Я бы даже не стал перезагружать эти данные целиком.

В данный момент я делаю это и чувствую себя очень грязно :)

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

   }

Это работает, но я уверен, что есть более эффективные способы разрешения конфликтов. (Слияние было бы, конечно, здорово!)

Пожалуйста, дайте мне знать, как лучше справиться с этим сценарием:)

1 Ответ

4 голосов
/ 14 ноября 2012

Эту проблему с конфликтами можно решить на сервере. Доменная служба является частичным классом, где вы можете переопределить метод ResolveConflicts.

Пример:

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