PRB: CommandBuilder가 수정된 명령을 다시 원래 명령으로 변경한다

기술 자료 번역 기술 자료 번역
기술 자료: 310366 - 이 문서가 적용되는 제품 보기.
이 문서는 이전에 다음 ID로 출판되었음: KR310366
이 문서가 보관되었습니다. "그대로" 제공되었으며, 업데이트가 되지 않을 것입니다.
모두 확대 | 모두 축소

이 페이지에서

현상

CommandBuilder 개체는 다음에 DataAdapter.Update 메서드를 호출할 때 사용자가 수정하려는 명령을 재작성할 수 있어 명령에 대한 변경 내용이 손실될 수 있습니다. 아래와 같은 경우에 이러한 문제가 발생합니다.
  • CommandBuilder 개체를 DataAdapter 개체와 연결한 경우
  • CommandBuilder 개체의 GetInsertCommand, GetUpdateCommand 또는 GetDeleteCommand 메서드를 사용하여 DataAdapter에 명시적으로 명령을 지정한 경우.
  • CommandBuilder가 만든 명령 중 하나를 수정한 경우
DataAdapterUpdate 메서드를 호출하려고 하면 다음과 같은 오류 메시지가 나타날 수 있습니다.
처리되지 않은 'System.Data.SqlClient.SqlException' 형식의 예외가 system.data.dll에서 발생했습니다.

원인

이 문제는 CommandBuilder가 자신이 만든 명령을 다시 원래 명령으로 동적으로 변경하기 때문에 발생합니다.

해결 방법

이 문제를 해결하려면 다음 방법 중 하나를 사용하십시오.
  • CommandBuilder가 만든 명령을 수정하지 않습니다. 사용자 자신이 작성한 Command 개체는 CommandBuilder가 변경하지 않습니다.
  • 새로운 DataAdapterInsertCommand, DeleteCommandUpdateCommand 개체를 복사합니다(예제는 "추가 정보" 절 참조). 새 DataAdapter 변수는 이전 DataAdapter 변수보다 좁거나 같은 범위를 가져야 합니다.
  • CommandBuilder를 사용하지 않아야 합니다. 사용자 자신의 Command 개체를 작성하거나 Visual Data Tools를 사용하여 작성합니다.

현재 상태

이것은 의도적으로 설계된 동작입니다.

추가 정보

문제를 재현하는 방법

  1. 새로운 Visual Basic Windows 응용 프로그램 프로젝트를 만듭니다. 기본적으로 Form1이 프로젝트에 추가됩니다.
  2. 폼을 두 번 누르고 코드 창의 맨 위에 다음 코드를 추가합니다.
    Imports System.Data.SqlClient
  3. Form1에 Button 컨트롤을 추가합니다.
  4. Button을 두 번 누르고 Click 이벤트에 다음 코드를 추가합니다.
    Dim cn As New SqlConnection()
            Dim custDS As New DataSet()
            Dim da1 As New SqlDataAdapter()
            Dim da2 As New SqlDataAdapter()
            Dim dr As DataRow
            Dim cb As SqlCommandBuilder
    
            cn.ConnectionString = "server=servername;database=northwind;uid=sa;pwd=password;"
            cn.Open()
            da1 = New SqlDataAdapter("select * from Customers", cn)
            cb = New SqlCommandBuilder(da1)
    
            da1.Fill(custDS, "Customers")
    
            'Get the original commands.
    
            da1.InsertCommand = cb.GetInsertCommand
            da1.DeleteCommand = cb.GetDeleteCommand
            da1.UpdateCommand = cb.GetUpdateCommand
    
            Debug.WriteLine("Original command length: " & da1.InsertCommand.CommandText.Length)
    
            'Modify the Insert command.
    
            da1.InsertCommand.CommandText = "select * from customers where customerid=@@identity"
    
            da1.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord
    
            da2.InsertCommand = da1.InsertCommand
            da2.DeleteCommand = da1.DeleteCommand
            da2.UpdateCommand = da1.UpdateCommand
    
            'Add a record to the table.
    
            Dim tblCust As DataTable
            tblCust = custDS.Tables("Customers")
    
            Dim drCust As DataRow
    
            drCust = tblCust.NewRow()
            drCust("CustomerID") = "ZYYYY"
            drCust("CompanyName") = "Zora's Yummies"
            drCust("ContactName") = "Christophe Namby"
            drCust("ContactTitle") = "Assistant Manager"
    
            tblCust.Rows.Add(drCust)
    
            'Update the backend.
    
            Debug.WriteLine("Length da1 before insert: " & da1.InsertCommand.CommandText.Length)
    
            da1.Update(custDS, "Customers")
    
            Debug.WriteLine("Length da1 after insert: " & da1.InsertCommand.CommandText.Length)
            Debug.WriteLine("length da2 before insert: " & da2.InsertCommand.CommandText.Length)
    
            da2.Update(custDS, "Customers")
    
            Debug.WriteLine("Length da2 after insert: " & da2.InsertCommand.CommandText.Length)
  5. 연결 문자열을 수정하여 해당 Microsoft SQL Server에 연결합니다.
  6. F5 키를 눌러 코드를 실행합니다.
  7. 이 문제를 해결하려면 다음 줄을 주석으로 처리합니다.
            da1.Update(custDS, "Customers")
CommandBuilder가 명령을 생성할 시기를 알 수 있도록 DataAdapter("da1")의 RowUpdating 이벤트에 연결되기 때문에 이러한 해결책이 적용됩니다. 명령을 다른 DataAdapter("da2")에 복사하면 CommandBuilder가 더 이상 해당 이벤트에 연결되지 않아 이벤트를 변경하지 않습니다.

"da1"과 SqlCommandBuilder("cb")가 범위를 벗어나고 가비지 수집이 발생하면 CommandBuilder가 해당 명령을 Nothing(Visual C#에서는 null)으로 설정하기 때문에 변수 범위가 중요합니다. 따라서 "da2"에서는 이들 명령을 사용할 수 없습니다. 언제든지 가비지 수집이 발생할 수 있으므로 da2.Update 메서드는 가끔씩 NullReferenceException 오류를 발생시킬 수 있습니다.

속성

기술 자료: 310366 - 마지막 검토: 2014년 2월 24일 월요일 - 수정: 1.0
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft ADO .NET(.NET Framework에 포함)
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
키워드:?
kbnosurvey kbarchive kbprb kbadonet KB310366

피드백 보내기

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com