2011-04-18 3 views
3

저는 Linq-to-SQL RIA 서비스와 Silverlight 클라이언트를 가지고 있습니다. 2 명이 동일한 엔터티를 편집 할 때 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; 
}