2011-04-18 104 views
3

我有一个Linq-to-SQL RIA服务和一个silverlight客户端。当两个人编辑相同的实体时,我调用SubmitChanges时会在OnSubmitCompleted中收到一个EntityConflict。 现在我想对它做出反应,而不会让用户烦恼太多,我只想给他看一个消息框,让他知道数据已被修改,并且他的更改将被服务器值覆盖。DomainContext中的冲突处理

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

    } 

这工作,但我相信有解决冲突的更好的方法。 (合并当然会是伟大的!)

请让我知道的更好的方法来处理这种情况:)

回答

4

这个问题与冲突,可以在服务器上得到解决。域服务是一个部分类,您可以覆盖方法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; 
}