2011-12-17 1 views
0

사용자가 메모를 작성하고 화면에서 계속 메모를 이동할 수있는 Todo 유형의 응용 프로그램을 만들고 있습니다.상수 업데이트 및 호출 submitchanges :이 엔티티는 현재 읽기 전용입니다. ria services

이의 일반적인 코드는 다음과 같습니다 :

private void SaveChanges() 
    { 
     if (!_context.IsSubmitting) 
     { 
      this.busyIndicator.IsBusy = true; 
      _context.SubmitChanges(subOp => 
      { 

       this.busyIndicator.IsBusy = false; 
       if (subOp.Error != null) 
       { 
        ErrorWindow window = new ErrorWindow(subOp.Error.Message); 
        window.Show(); 
       } 

      }, null); 
     } 
    } 

그러나 당신은 내가 busyindicator를 사용 중지하여 UI를 차단하고 볼 수있는 "노트"의 위치의 모든 변경에 나는 데이터베이스에 저장해야 사용자가 제출하는 동안 모든 활동을 수행해야합니다. 이것은 특히이 응용 프로그램에 좋지 않습니다. 따라서 대안으로이 코드를 사용하여이 코드를 다른 스레드로 옮기려고 시도했습니다.

private void SaveChanges() 
    { 
     ThreadPool.QueueUserWorkItem(waitcall => 
     { 
      if (!_context.IsSubmitting) 
      { 
       //this.busyIndicator.IsBusy = true; 
       _context.SubmitChanges(subOp => 
       { 
        Dispatcher.BeginInvoke(() => 
        { 
         //this.busyIndicator.IsBusy = false; 
         if (subOp.Error != null) 
         { 
          ErrorWindow window = new ErrorWindow(subOp.Error.Message); 
          window.Show(); 
         } 
        }); 

       }, null); 
      } 

     }); 
    } 

이 방법은 여전히 ​​작동하며 응용 프로그램은 여전히 ​​응답합니다. 그러나 지금은 상황이 변경 사항을 제출하고 사용자는 개체의 속성을 변경하려면 바인딩을 시도 화면 주위 등 이동하여 같은 음으로 작동하고 나는 예외다면 :

이 단체는 현재 읽기 전용

컨텍스트에서 변경 사항을 제출하기 때문에 이것이 분명하다는 것을 알고 있습니다. 그러나 바쁜 통화 중 표시기를 표시하지 않고 여전히 이러한 예외가 발생하지 않도록하여 응용 프로그램을 응답 가능하게 유지할 수있는 방법이 있습니까?

+0

당신이 모든 변경에 구원이되는 이유는 무엇입니까? 사용자가 제출하기 전에 변경을 멈출 때까지 기다리지 않으시겠습니까? – Yahia

+0

모든 변경 사항을 저장하면 "사용자가 메모를 이동하지 않습니다"라는 의미입니다. 사용자가 노트 이동을 멈 추면 저장해야합니다.일반적으로 이런 일이 발생합니다 : 1) 사용자가 메모를 이동 "중지"2) submitchanges 화재 3) submatchanges 동안, 사용자가 메모 및 예외 화재를 다시 이동합니다. – TCM

+0

귀하의 코드처럼 들리네요 reentrancy와 제대로 처리하지 ... 왜 그냥 두 번째 변경 제출 첫 번째 제출 완료 후? – Yahia

답변

1

SubmitChanges 동안 변경된 모든 속성은 읽기 전용으로 설정됩니다. 귀하의 경우, 그것은 위치 속성입니다. 속성이 노트 위치에 바인딩되어 있다고 추측합니다.

Possiblities는 :

  1. 은 DomainContext의 실체에 결합하지 마십시오. 프로퍼티가 변경된 이벤트 (아마도 엔티티의 복제본)가있는 클라이언트 로컬 객체에 바인딩합니다. 변경된 특성 이벤트를 사용하여 변경 사항을 컨텍스트 엔티티에 복사하십시오. 실패하면 (읽기 전용) 나중에 코드를 추가하여 다시 시도 할 수 있습니다.

  2. RIA Services Contrib에서 EntityGraph 부분 제출을 사용하십시오. riaservicescontrib.codeplex.com 토론/블로그를 확인하십시오 - EntityGraph를 임시 컨텍스트에 복제하고 임시 컨텍스트를 제출하는 코드가 제공됩니다. 나는 그것이 아마도 새로운 위치를 덮어 씌우고 창을 뛰어 넘을 수 있기 때문에 당신이 완료시 동기화를하고 싶지 않을 것이라고 생각합니다. 그냥 제출하고 잊어 버려. 클라이언트에 엔터티를 추가하는 경우 서버에서 반환 된 자동 생성 된 키 속성 (ID 등)이 필요합니다. 그런 다음 추가를 위해 임시 컨텍스트/부분 제출을 사용하지 마십시오. UI를 차단하고 추가를 정상적으로 제출하면 완료시 클라이언트 속성이 업데이트되고 키 값이 설정되기 전에 부분 제출이 호출되지 않습니다.

다른 가능한 솔루션에도 관심이 있습니다.

+0

나는 당신의 해결책을 좋아합니다. 다른 솔루션 중 하나는 SubmitChanges를 호출하는 대신 Stored procedure를 사용하는 것입니다. – TCM

0

또한 뛰어난 제출 작업의 수의 스레드 수를 유지하고 현재 제출 작업의 콜백에서 다음 중 하나를 팝업 수 :

public static int myPendingSubmitOperationsCount; 
... 
myDataContext.SubmitChanges(mySubmitCallback, null); 
... 
mySubmitCallback(SubmitOperation so) 
{ 
    //Do important stuff 
    if(myPendingSubmitOperationsCount > 0) 
    { 
     myDataContext.SubmitChanges(mySubmitCallback, null); 
     myPendingSubmitOperationsCount -= 1; 
    } 
}