2011-04-18 114 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; 
}