앞서 언급했듯이 데이터 바인딩 컨트롤은 데이터 소스에 전달된 값을 독립적인 Keys, Values (새 값) 및 OldValues 사전에 저장합니다. 기본적으로 SqlDataSource 및 ObjectDataSource는 OldValues 필드를 무시하고 키와 값만 사용합니다. 이 동작은 기본적으로 OverwriteChanges로 설정되는 데이터 소스의 ContributeDetection 속성에 의해 감지됩니다. OverwriteChanges 패턴은 "레코드를 업데이트하거나 삭제하기 위해 기본 키 값과만 일치한다"는 의미입니다. 이 작업은 레코드 업데이트 또는 삭제 시 레코드의 기본 값이 변경되었는지 여부를 고려하지 않음을 의미합니다. 일반적인 상황에서 이상적인 상태는 데이터 행의 값이 원래 선택한 값과 정확히 일치하는 경우에만 업데이트 또는 삭제 작업이 성공하도록 허용하는 것입니다. 이러한 이상적인 상황에서는 귀하가 행을 선택한 시점과 업데이트한 시점 사이에 다른 사용자가 행을 업데이트하면 업데이트 작업이 실패하게 됩니다. 데이터 원본은 ContributeDetection 속성을 CompareAllValues로 설정하여 이 작업도 지원합니다. 이 모드에서 데이터 소스는 OldValues를 명령이나 메서드에 적용하고 이러한 값을 사용하여 업데이트 또는 삭제 작업이 레코드를 업데이트하거나 삭제하기 전에 레코드의 모든 값과 일치해야 함을 확인합니다. 기록. 또한 OldValues 및 Keys 사전의 매개 변수 이름을 변경하여 NewValues 매개 변수와 구별해야 하는 방법을 나타내려면 OldValuesParameterFormatString 속성을 유효한 .NET Framework 구성 요소 형식 문자열(예: "original_{0}")로 설정해야 합니다.
다음 코드 예제에서는 OverwriteChanges 및 CompareAllValues 모드에서 SqlDataSource 컨트롤에 사용되는 일반적인 SQL 명령을 보여줍니다. ID 필드는 기본 키 필드로 간주됩니다. 후자의 명령은 기본 키뿐만 아니라 WHERE 절에 있는 데이터 행의 모든 원시 값을 비교합니다. 이 경우 데이터 소스의 OldValuesParameterFormatString을 "original_{0}"으로 설정해야 합니다.
[연락처]에서 [ID], [이름], [주소]를 선택하세요.
-- 변경 사항 덮어쓰기
UPDATE [연락처] SET [이름] = @이름, [주소] = @주소 WHERE [ID] = @ID
[연락처] WHERE [ID] = @ID에서 삭제
-- CompareAllValues
UPDATE [연락처] SET [이름] = @이름, [주소] = @주소 WHERE [ID] = @original_ID
AND [이름] = @original_Name AND [주소] = @original_Address
[연락처]에서 삭제합니다. 여기서 [ID] = @original_ID AND [이름] = @original_Name
AND [Address] = @original_Address
삽입 작업에는 OldValues가 필요하지 않으며 ContributeDetection은 업데이트 및 삭제 작업에만 의미가 있다는 점에 유의하세요.
다음 예에서는 충돌이 발생할 때의 동작을 보여줍니다. 이 예제를 실행하려면 두 개의 별도 브라우저 창에서 예제의 두 인스턴스를 열어야 합니다("샘플 실행"을 두 번 클릭). 그런 다음 두 양식의 동일한 행에서 "편집" 버튼을 클릭하여 해당 행을 편집 모드로 전환합니다. 첫 번째 창에서 값을 변경하고 "업데이트"를 클릭하면 업데이트가 완료되었습니다. 두 번째 창에서는 행에 새 값을 입력하고 "업데이트"를 클릭합니다. 기본 데이터 행의 값이 첫 번째 업데이트 작업에 의해 이미 변경되었기 때문에 이 업데이트 작업은 성공하지 못합니다. 이 예에서는 충돌이 발생했는지 확인하기 위해 업데이트됨 또는 삭제됨 이벤트 매개 변수(0)의 AffectedRows 속성을 확인합니다.
<스크립트 runat="서버">
보호된 하위 SqlDataSource1_Updated(개체로 보낸 사람, SqlDataSourceStatusEventArgs로 e)
e.AffectedRows = 0인 경우
Response.Write("행 변경, 업데이트 중단됨
")
종료 조건
End Sub
보호된 하위 SqlDataSource1_Deleted(개체로 보낸 사람, SqlDataSourceStatusEventArgs로 e)
e.AffectedRows = 0인 경우
Response.Write("행 변경, 삭제 중단됨
")
종료 조건
서브 끝
업데이트 또는 삭제가 템플릿 UI를 사용하는 경우 Bind 구문을 사용하는 양방향 데이터 바인딩 필드의 이전 값이 유지됩니다. 삭제의 경우 ItemTemplate에서 데이터 바인딩된 값에 대해 Bind 구문을 사용해야 함을 의미합니다. 목적은 삭제 작업에 필요한 이전 값을 유지하는 것입니다. 다음 예에서는 이 기술을 보여줍니다.
<아이템템플릿>
아이템템플릿>
<EditItemTemplate>
<아이템템플릿>
아이템템플릿>
<EditItemTemplate>
칼럼>
사용자에게 기본 데이터가 변경되었음을 알리고 변경된 값을 사용자에게 표시하며 사용자가 작업 제출 또는 포기를 선택할 수 있도록 하여 충돌 감지 오류를 부드럽게 처리할 수 있습니다. 다음 예에서는 충돌 감지를 처리하는 한 가지 가능한 방법을 보여줍니다. DetailsView의 RowUpdated 이벤트 매개변수에는 사용자가 입력한 값을 검색하는 데 사용할 수 있는 사전이 전달됩니다. 또한 이 이벤트 매개 변수의 KeepInEditMode 속성을 설정하여 사용자가 충돌 처리 방법을 결정하는 동안 DetailsView를 편집 모드로 유지할 수도 있습니다. 이 예에서는 두 개의 창을 동시에 열어 충돌하는 업데이트를 생성하는 이전 방법과 유사한 접근 방식을 테스트합니다.
보호된 하위 세부 정보View1_ItemUpdated(ByVal 보낸 사람을 개체로, ByVal e를 System.Web.UI.WebControls.DetailsViewUpdatedEventArgs로)
e.AffectedRows = 0인 경우
' DetailsView를 편집 모드로 두고 데이터베이스와 동기화합니다. e.KeepInEditMode = True
세부정보View1.DataBind()
' 사용자가 입력한 값으로 DetailsView를 다시 채웁니다.
텍스트 상자로 희미하게
t = DetailsView1.Rows(1).Cells(1).Controls(0)
t.Text = e.NewValues("OrderDate")
t = DetailsView1.Rows(2).Cells(1).Controls(0)
t.Text = e.NewValues("ShipCountry")
ErrorPanel.Visible = True
또 다른
ErrorPanel.Visible = 거짓
종료 조건
End Sub
Protected Sub DetailsView1_ModeChanging(ByVal 보낸 사람을 개체로, ByVal e를 System.Web.UI.WebControls.DetailsViewModeEventArgs로)
e.CancelingEdit = True AndAlso ErrorPanel.Visible = True이면
ErrorPanel.Visible = 거짓
종료 조건
End Sub가
경우 상황은 비슷합니다
.데이터 소스의 ContributeDetection 속성이 CompareAllValues로 설정되어 있으므로 데이터 소스는 Contact 개체의 각 필드에 대한 원시 값을 허용하는 UpdateContact 오버로드를 찾습니다.
DataObjectTypeName 속성과 CompareAllValues를 함께 사용할 수도 있습니다. 이 경우 ObjectDataSource는 두 개의 매개 변수(모두 Contact)만 허용하는 UpdateContact 오버로드를 찾습니다. 첫 번째 매개변수는 새 값이 저장되는 Contact 개체이고, 두 번째 매개변수는 이전 값이 저장되는 Contact 개체입니다.