2011-08-11 7 views
1

내 응용 프로그램에는 데이터베이스 테이블의 내용을 사용자에게 표시하는 컨트롤이 있습니다. 이 컨트롤은 System.Data.DataSet 개체에 표시 할 데이터를 보유합니다. 사용자는 컨트롤에 표시된 데이터를 수정할 수 있으며이 데이터는 사용자가 완료되면 다시 데이터베이스에 커밋됩니다.SqlDataAdapter.Update가 자동으로 실패합니다.

사용자가 컨트롤을 편집하는 동안 일부 외부 프로세스 (예 : 일부 행이 업데이트 됨)로 데이터베이스 테이블의 데이터가 수정되면 문제가 발생합니다. 현재 데이터의 정확성 문제를 무시하고 사용자가 컨트롤에서 변경 한 사항을 커밋하고이 외부 프로세스에서 변경 한 내용을 덮어 쓰려고합니다.

나는 SqlDataAdapter을 사용하여 데이터베이스를 업데이트하고 있습니다. 설명 된 사용 사례에서 기본 데이터베이스 테이블이 외부 프로세스에 의해 수정되지 않은 경우 SqlDataAdapter.Update이 예상대로 작동합니다. 그러나 사용자가 테이블을 편집하는 동안 일부 외부 프로세스가 테이블을 조작하는 시나리오에서는 SqlDataAdapter.Update이 예외를 throw하지 않지만 업데이트 된 행이 없음을 나타내는 0을 반환합니다. 데이터 세트의 행에 올바른 데이터가 있고 RowState (즉 DataRowState.Modified) 인 것을 확인 했으므로 SqlDataAdapter.Update 메소드로 전달되는 데이터가 정확하다는 것을 알고 있습니다.

내 질문에 두 부분이 있다고 가정합니다.

  1. SqlDataAdapter.Update은 지정된 데이터 세트로 데이터베이스를 업데이트하지 않습니까?
  2. 조용히 실패하는 이유는 무엇입니까?

것은 내가 this blog entry을 읽고, 내 코드는 어디 AcceptChanges를 호출하지 않고, 내가 위에서 언급했듯이 나는 DataSetRowState는 그래서 행이 올바르게 수정 된 데이터를 필요로 표시되는 것을 알고 확인했다.

답변

1

테이블의 구조는 무엇이며 사용하는 버전 관리 메커니즘 (타임 스탬프, 날짜 시간 등)은 무엇입니까? SqlDataAdapter이 궁극적으로 버전 관리를 처리하는 방법에 영향을 미칠 수있는 여러 가지가 있지만 내 생각에 테이블에 타임 스탬프가 있거나 (GetUpdateCommand 메서드를 통해)을 생성하는 SqlCommandBuilder이 있습니다. 업데이트 한 행의 이전 값에 대한 데이터베이스의 행에있는 값 (DataRow은 비교를 위해 이전 버전의 행을 저장합니다).

ADO.NET이 당신을 위해 optimistic concurrency을 시도하고 유지하려고하기 때문에이 모든 것이 중요한 역할을합니다. 마지막으로 가져온 이후 다른 사람이 레코드를 수정 한 경우 업데이트가 발생하지 않습니다.

이것은 분명히 원하는 동작이 아닙니다. 마지막으로이기는 방식이 필요합니다. SqlDataAdapter 업데이트를 수행하고 타임 스탬프를 확인하지 것이다 SqlCommand에 명시 적으로 UpdateCommand 속성을 설정에

가, 이렇게하려면, 그것은 단지 기본 키는 사용자가 지정한 DataRow의 값과 같은 기록을 갱신 (또는 고유 한 제한 조건이있는 열의 값).

+0

타임 스탬프가 문제였습니다. SqlDataAdapter는 SqlCommandBuilder에 래핑되었으며 SqlDataAdapter의 select 명령은 타임 스탬프를 검색했습니다.이 타임 스탬프는 차례대로 자동 생성 된 UPDATE 명령이 타임 스탬프를 쿼리의 일부로 사용함을 의미합니다. 타임 스탬프를 무시한 명시 적 업데이트 명령을 작성하면 문제가 해결되었습니다.SQL 프로파일 러를 파기하는 것이 재미 있지 않기 때문에 나는 당신의 대답을 더 빨리 보길 바랬다. – CadentOrange

+0

@Philip Goh : 나는 단지 1 시간 만에 내 대답을 더 빨리 볼 수 있었는지 모른다. 전에. =) – casperOne

관련 문제