연습: 로컬 데이터베이스 캐시를 확장하여 양방향 동기화 지원
Visual Studio 2008에서 로컬 데이터베이스 캐시는 Sync Framework을 지원하는 SQL Server Compact 데이터베이스 및 partial 클래스 집합을 구성합니다. Visual Studio에서는 partial 클래스를 생성하므로 데이터 동기화 구성 대화 상자에서 설정을 확인하고 변경하는 기능을 유지하면서 동기화 기능을 추가하는 코드를 작성할 수 있습니다. 로컬 데이터베이스 캐시 및 partial 클래스에 대한 자세한 내용은 Visual Studio 2008 설명서를 참조하십시오.
기본적으로는 데이터 동기화 구성 대화 상자를 통해 다운로드 시나리오에 대해서만 Sync Framework를 구성할 수 있습니다. 즉, 데이터 동기화를 구성한 후 Synchronize를 호출하면 서버에서 클라이언트 데이터베이스로 변경 내용이 다운로드되기만 합니다. 동기화 코드를 확장하는 가장 일반적인 방법 중 하나는 양방향 동기화를 구성하는 것입니다. 이렇게 하면 클라이언트에서 서버로 변경 내용을 업로드할 수 있습니다. 양방향 동기화를 구현하려면 생성된 코드를 다음과 같은 방법으로 확장하는 것이 좋습니다.
동기화 방향을 양방향으로 설정합니다.
동기화 충돌을 처리하는 코드를 추가합니다.
동기화 명령에서 서버 추적 열을 제거합니다.
참고
Visual Studio 2008에서는 로컬 데이터베이스 캐시에 대한 코드를 생성할 때 Sync Framework for ADO.NET 1.0을 사용합니다.
필수 구성 요소
이 연습을 시작하기 전에 Visual Studio 2008 설명서의 "연습: 자주 연결하는 응용 프로그램 만들기"를 완료해야 합니다. 이 연습을 완료하면 로컬 데이터베이스 캐시가 들어 있는 프로젝트 및 Northwind Customers 테이블의 변경 내용을 SQL Server Compact 데이터베이스로 다운로드할 수 있는 Windows Form 응용 프로그램이 준비됩니다. 그런 다음 이 연습을 로드하여 양방향 기능을 추가할 수 있습니다.
OCSWalkthrough 솔루션을 열려면
Visual Studio를 엽니다.
파일 메뉴에서 기존 솔루션이나 프로젝트를 열고 OCSWalkthrough 솔루션을 찾습니다. 이 솔루션은 OCSWalkthrough.sln 파일입니다.
동기화 방향 설정
데이터 동기화 구성 대화 상자는 SyncDirection 속성을 DownloadOnly 또는 Snapshot으로 설정합니다. 양방향 동기화를 사용하려면 변경 내용을 업로드할 수 있게 만들 각 테이블의 SyncDirection 속성을 Bidirectional로 설정합니다.
동기화 방향을 설정하려면
NorthwindCache.sync를 마우스 오른쪽 단추로 클릭하고 코드 보기를 선택합니다. 이 작업을 처음 수행하면 Visual Studio에서 솔루션 탐색기의 NorthwindCache.sync 노드 아래에 NorthwindCache 클래스 파일을 만듭니다. 이 파일에는
NorthwindCacheSyncAgent
partial 클래스가 들어 있으며 다른 클래스를 필요에 따라 추가할 수 있습니다.NorthwindCache 클래스 파일에서
NorthwindCacheSyncAgent.OnInitialized()
메서드에 다음 코드 줄을 추가합니다.public partial class NorthwindCacheSyncAgent { partial void OnInitialized() { this.Customers.SyncDirection = Microsoft.Synchronization.Data.SyncDirection.Bidirectional; } }
Partial Public Class NorthwindCacheSyncAgent Partial Sub OnInitialized() Me.Customers.SyncDirection = Microsoft.Synchronization.Data.SyncDirection.Bidirectional End Sub End Class
코드 편집기에서 Form1을 엽니다.
Form1 파일에서
SynchronizeButton_Click
이벤트 처리기의 코드 줄을 편집하여 업로드 및 다운로드 통계를 포함합니다.MessageBox.Show("Changes downloaded: " + syncStats.TotalChangesDownloaded.ToString() + Environment.NewLine + "Changes uploaded: " + syncStats.TotalChangesUploaded.ToString());
MessageBox.Show("Changes downloaded: " & _ syncStats.TotalChangesDownloaded.ToString & Environment.NewLine & "Changes uploaded: " & _ syncStats.TotalChangesUploaded.ToString)
동기화를 수행하고 통계를 보려면
F5 키를 누릅니다.
폼에서 레코드를 업데이트한 다음 도구 상자에서 Save 단추를 클릭합니다.
Synchronize Now를 클릭합니다.
동기화된 레코드에 대한 정보가 들어 있는 메시지 상자가 나타납니다. 서버에는 변경 내용이 없지만 통계를 보면 행 하나가 업로드되었고 행 하나가 다운로드되었음을 알 수 있습니다. 추가 다운로드가 발생한 이유는 클라이언트의 변경 내용이 서버에 적용된 후 클라이언트에 반환되었기 때문입니다. 자세한 내용은 방법: 사용자 지정 변경 내용 추적 시스템 사용에서 "데이터를 변경한 클라이언트 확인"을 참조하십시오.
확인을 클릭하여 메시지 상자를 닫고 응용 프로그램을 실행 상태로 유지합니다.
동기화를 수행하고 충돌 해결을 보려면
폼에서 레코드를 업데이트한 다음 Save 단추를 클릭합니다.
응용 프로그램이 계속 실행되는 상태에서 서버 탐색기/데이터베이스 탐색기 또는 기타 데이터베이스 관리 도구를 사용하여 서버 데이터베이스에 연결합니다.
기본 충돌 해결 동작을 보려면 폼에서 업데이트한 레코드를 서버 탐색기/데이터베이스 탐색기에서 다른 값으로 업데이트하고 변경 내용을 커밋합니다. 그런 다음 수정된 행을 벗어납니다.
폼으로 돌아간 다음 Synchronize Now를 클릭합니다.
응용 프로그램 표와 서버 데이터베이스에서 업데이트를 확인합니다. 서버에서 업데이트한 내용이 클라이언트의 업데이트를 덮어썼습니다. 이 충돌 해결 동작을 변경하는 방법에 대한 자세한 내용은 이 항목의 다음 단원인 "동기화 충돌을 처리하는 코드 추가"를 참조하십시오.
동기화 충돌을 처리하는 코드 추가
동기화 간에 클라이언트와 서버에서 모두 변경된 행은 Sync Framework에서 충돌 상태로 간주됩니다. Sync Framework에서는 충돌을 검색하고 해결하는 데 사용할 수 있는 여러 가지 기능을 제공합니다. 이 연습에서는 클라이언트와 서버에서 같은 행이 업데이트된 경우의 충돌을 처리하는 기본적인 기능을 추가합니다. 다른 종류의 충돌로는 데이터베이스 하나에서는 삭제된 행이 다른 데이터베이스에서 업데이트되었거나 기본 키가 중복되는 행이 두 데이터베이스에 모두 삽입된 경우가 있습니다. 충돌을 검색하고 해결하는 방법에 대한 자세한 내용은 방법: 데이터 충돌 및 오류 처리를 참조하십시오.
충돌 처리를 추가하려면
서버의 ApplyChangeFailed 이벤트 및 클라이언트의 ApplyChangeFailed 이벤트를 처리하는 코드를 추가합니다. 이러한 이벤트는 충돌이나 오류로 인해 행을 적용할 수 없을 때 발생합니다. 샘플 코드에서 이러한 이벤트를 처리하는 메서드는 충돌의 종류를 확인하고 클라이언트 변경 내용을 강제로 서버 데이터베이스에 쓰는 방법으로 클라이언트 업데이트/서버 업데이트 충돌을 해결하도록 지정합니다. 업데이트를 서버 데이터베이스에 적용하는 동기화 명령에는 변경 내용을 강제 적용하는 경우를 인식하는 논리가 포함되어 있습니다. 이 명령은 이 항목의 다음 단원인 "동기화 명령에서 서버 추적 열 제거"의 코드에 포함되어 있습니다.
참고
샘플 코드에서는 기본적인 충돌 처리 예제를 제공합니다. 실제로 충돌을 처리하는 방법은 응용 프로그램의 요구 사항과 비즈니스 논리에 따라 다릅니다.
C#에서 코드를 추가하는 방법은 Visual Basic의 경우와 다릅니다.
C#의 경우 NorthwindCache.cs 및 Form1.cs에 코드를 추가합니다. NorthwindCache.cs에서
NorthwindCacheSyncAgent
클래스 끝 뒤에 다음 코드를 추가합니다.public partial class NorthwindCacheServerSyncProvider { partial void OnInitialized() { this.ApplyChangeFailed += new System.EventHandler<Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs> (NorthwindCacheServerSyncProvider_ApplyChangeFailed); } private void NorthwindCacheServerSyncProvider_ApplyChangeFailed(object sender, Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e) { if (e.Conflict.ConflictType == Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate) { //Resolve a client update / server update conflict by force writing //the client change to the server database. System.Windows.Forms.MessageBox.Show("A client update / server update conflict " + "was detected at the server."); e.Action = Microsoft.Synchronization.Data.ApplyAction.RetryWithForceWrite; } } } public partial class NorthwindCacheClientSyncProvider { public void AddHandlers() { this.ApplyChangeFailed += new System.EventHandler<Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs> (NorthwindCacheClientSyncProvider_ApplyChangeFailed); } private void NorthwindCacheClientSyncProvider_ApplyChangeFailed(object sender, Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e) { if (e.Conflict.ConflictType == Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate) { //Resolve a client update / server update conflict by keeping the //client change. e.Action = Microsoft.Synchronization.Data.ApplyAction.Continue; } } }
Form1.cs에서
SynchronizeButton_Click
이벤트 처리기의 코드를 편집하여 이전 단계에서 NorthwindCache.cs에 추가한AddHandlers
메서드를 호출합니다.NorthwindCacheSyncAgent syncAgent = new NorthwindCacheSyncAgent(); NorthwindCacheClientSyncProvider clientSyncProvider = (NorthwindCacheClientSyncProvider)syncAgent.LocalProvider; clientSyncProvider.AddHandlers(); Microsoft.Synchronization.Data.SyncStatistics syncStats = syncAgent.Synchronize();
Visual Basic의 경우 NorthwindCache.vb에서
NorthwindCacheSyncAgent
클래스의End Class
명령문 뒤에 다음 코드를 추가합니다.Partial Public Class NorthwindCacheServerSyncProvider Private Sub NorthwindCacheServerSyncProvider_ApplyChangeFailed( _ ByVal sender As Object, ByVal e As _ Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs) _ Handles Me.ApplyChangeFailed If e.Conflict.ConflictType = _ Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate Then 'Resolve a client update / server update conflict by force writing 'the client change to the server database. MessageBox.Show("A client update / server update conflict was detected at the server.") e.Action = Microsoft.Synchronization.Data.ApplyAction.RetryWithForceWrite End If End Sub End Class Partial Public Class NorthwindCacheClientSyncProvider Private Sub NorthwindCacheClientSyncProvider_ApplyChangeFailed( _ ByVal sender As Object, ByVal e As _ Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs) _ Handles Me.ApplyChangeFailed If e.Conflict.ConflictType = _ Microsoft.Synchronization.Data.ConflictType.ClientUpdateServerUpdate Then 'Resolve a client update / server update conflict by keeping the 'client change. e.Action = Microsoft.Synchronization.Data.ApplyAction.Continue End If End Sub End Class
동기화를 수행하고 충돌 해결을 보려면
F5 키를 누릅니다.
폼에서 레코드를 업데이트한 다음 Save 단추를 클릭합니다.
폼에서 업데이트한 레코드를 서버 탐색기/데이터베이스 탐색기에서 다른 값으로 업데이트하고 변경 내용을 커밋합니다.
폼으로 돌아간 다음 Synchronize Now를 클릭합니다.
응용 프로그램 표와 서버 데이터베이스에서 업데이트를 확인합니다. 클라이언트에서 업데이트한 내용이 서버의 업데이트를 덮어썼습니다.
동기화 명령에서 서버 추적 열 제거
로컬 데이터베이스 캐시가 만들어지면 서버 데이터베이스의 변경 내용을 추적하는 데 사용되는 열이 클라이언트로 다운로드됩니다. 이 연습에서 이러한 열은 CreationDate
및 LastEditDate
입니다. 양방향 동기화를 지원하고 클라이언트와 서버의 데이터가 서로 일치하게 하려면 서버 데이터베이스에 변경 내용을 적용하는 SQL 명령에서 이러한 열을 제거합니다. 클라이언트에 적용할 변경 내용을 서버에서 선택하는 명령에서도 이러한 열을 제거할 수 있지만 이는 필수 작업은 아닙니다. 클라이언트 데이터베이스의 일부 스키마 변경에 대한 제한 사항으로 인해 이러한 열을 삭제할 수는 없습니다. 동기화 명령에 대한 자세한 내용은 방법: 스냅숏, 다운로드, 업로드 및 양방향 동기화 지정을 참조하십시오.
참고
SQL Server 변경 내용 추적을 사용하는 경우에는 테이블에 추적 열이 추가되지 않습니다. 이러한 경우 서버에 변경 내용을 적용하는 명령을 변경할 필요가 없습니다.
동기화 명령에서 서버 추적 열을 제거하려면
NorthwindCacheServerSyncProvider
클래스의End Class
명령문 뒤에서NorthwindCache
클래스(NorthwindCache.vb 또는 NorthwindCache.cs)에 다음 코드를 추가합니다. 이 코드에서는Customers
테이블의 SyncAdapter 개체에 있는 속성으로 설정되는 두 명령을 다시 정의합니다. 이러한 속성은 InsertCommand 및 UpdateCommand 속성입니다. 데이터 동기화 구성 대화 상자에서 생성한 명령에는CreationDate
및LastEditDate
열에 대한 참조가 들어 있습니다.CustomersSyncAdapter
클래스의OnInitialized
메서드에서 이러한 명령을 다시 정의합니다. DeleteCommand 속성은CreationDate
또는LastEditDate
열에 영향을 주지 않으므로 다시 정의되지 않습니다.각 SQL 명령의 변수는 Sync Framework, 클라이언트 및 서버 사이에서 데이터와 메타데이터를 전달하는 데 사용됩니다. 다음과 같은 세션 변수가 아래 명령에서 사용됩니다.
@sync_row_count
: 서버에서 마지막으로 수행한 작업이 적용된 행의 수를 반환합니다. SQL Server 데이터베이스에서는 @@ROWCOUNT가 이 변수의 값을 제공합니다.@sync_force_write
: 충돌이나 오류로 인해 실패한 변경 내용을 강제로 적용하는 데 사용됩니다.@sync_last_received_anchor
: 세션 중에 동기화할 변경 내용 집합을 정의하는 데 사용됩니다.
세션 변수에 대한 자세한 내용은 방법: 세션 변수 사용을 참조하십시오.
public partial class CustomersSyncAdapter { partial void OnInitialized() { //Redefine the insert command so that it does not insert values //into the CreationDate and LastEditDate columns. System.Data.SqlClient.SqlCommand insertCommand = new System.Data.SqlClient.SqlCommand(); insertCommand.CommandText = "INSERT INTO dbo.Customers ([CustomerID], [CompanyName], " + "[ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], " + "[Country], [Phone], [Fax] )" + "VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, " + "@Region, @PostalCode, @Country, @Phone, @Fax) SET @sync_row_count = @@rowcount"; insertCommand.CommandType = System.Data.CommandType.Text; insertCommand.Parameters.Add("@CustomerID", System.Data.SqlDbType.NChar); insertCommand.Parameters.Add("@CompanyName", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@ContactName", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@ContactTitle", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@Address", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@City", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@Region", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@PostalCode", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@Country", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@Phone", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@Fax", System.Data.SqlDbType.NVarChar); insertCommand.Parameters.Add("@sync_row_count", System.Data.SqlDbType.Int); insertCommand.Parameters["@sync_row_count"].Direction = System.Data.ParameterDirection.Output; this.InsertCommand = insertCommand; //Redefine the update command so that it does not update values //in the CreationDate and LastEditDate columns. System.Data.SqlClient.SqlCommand updateCommand = new System.Data.SqlClient.SqlCommand(); updateCommand.CommandText = "UPDATE dbo.Customers SET [CompanyName] = @CompanyName, [ContactName] " + "= @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] " + "= @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, " + "[Phone] = @Phone, [Fax] = @Fax " + "WHERE ([CustomerID] = @CustomerID) AND (@sync_force_write = 1 " + "OR ([LastEditDate] <= @sync_last_received_anchor)) SET @sync_row_count = @@rowcount"; updateCommand.CommandType = System.Data.CommandType.Text; updateCommand.Parameters.Add("@CompanyName", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@ContactName", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@ContactTitle", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@Address", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@City", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@Region", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@PostalCode", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@Country", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@Phone", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@Fax", System.Data.SqlDbType.NVarChar); updateCommand.Parameters.Add("@CustomerID", System.Data.SqlDbType.NChar); updateCommand.Parameters.Add("@sync_force_write", System.Data.SqlDbType.Bit); updateCommand.Parameters.Add("@sync_last_received_anchor", System.Data.SqlDbType.DateTime); updateCommand.Parameters.Add("@sync_row_count", System.Data.SqlDbType.Int); updateCommand.Parameters["@sync_row_count"].Direction = System.Data.ParameterDirection.Output; this.UpdateCommand = updateCommand; } }
Partial Public Class CustomersSyncAdapter Private Sub OnInitialized() 'Redefine the insert command so that it does not insert values 'into the CreationDate and LastEditDate columns. Dim insertCommand As New System.Data.SqlClient.SqlCommand With insertCommand .CommandText = "INSERT INTO dbo.Customers ([CustomerID], [CompanyName], " & _ "[ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], " & _ "[Country], [Phone], [Fax] )" & _ "VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, " & _ "@Region, @PostalCode, @Country, @Phone, @Fax) SET @sync_row_count = @@rowcount" .CommandType = System.Data.CommandType.Text .Parameters.Add("@CustomerID", System.Data.SqlDbType.NChar) .Parameters.Add("@CompanyName", System.Data.SqlDbType.NVarChar) .Parameters.Add("@ContactName", System.Data.SqlDbType.NVarChar) .Parameters.Add("@ContactTitle", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Address", System.Data.SqlDbType.NVarChar) .Parameters.Add("@City", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Region", System.Data.SqlDbType.NVarChar) .Parameters.Add("@PostalCode", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Country", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Phone", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Fax", System.Data.SqlDbType.NVarChar) .Parameters.Add("@sync_row_count", System.Data.SqlDbType.Int) .Parameters("@sync_row_count").Direction = ParameterDirection.Output End With Me.InsertCommand = insertCommand 'Redefine the update command so that it does not update values 'in the CreationDate and LastEditDate columns. Dim updateCommand As New System.Data.SqlClient.SqlCommand With updateCommand .CommandText = "UPDATE dbo.Customers SET [CompanyName] = @CompanyName, [ContactName] " & _ "= @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] " & _ "= @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, " & _ "[Phone] = @Phone, [Fax] = @Fax " & _ "WHERE ([CustomerID] = @CustomerID) AND (@sync_force_write = 1 " & _ "OR ([LastEditDate] <= @sync_last_received_anchor)) SET @sync_row_count = @@rowcount" .CommandType = System.Data.CommandType.Text .Parameters.Add("@CompanyName", System.Data.SqlDbType.NVarChar) .Parameters.Add("@ContactName", System.Data.SqlDbType.NVarChar) .Parameters.Add("@ContactTitle", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Address", System.Data.SqlDbType.NVarChar) .Parameters.Add("@City", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Region", System.Data.SqlDbType.NVarChar) .Parameters.Add("@PostalCode", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Country", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Phone", System.Data.SqlDbType.NVarChar) .Parameters.Add("@Fax", System.Data.SqlDbType.NVarChar) .Parameters.Add("@CustomerID", System.Data.SqlDbType.NChar) .Parameters.Add("@sync_force_write", System.Data.SqlDbType.Bit) .Parameters.Add("@sync_last_received_anchor", System.Data.SqlDbType.DateTime) .Parameters.Add("@sync_row_count", System.Data.SqlDbType.Int) .Parameters("@sync_row_count").Direction = ParameterDirection.Output End With Me.UpdateCommand = updateCommand End Sub End Class
동기화를 수행하고 추적 열 업데이트를 보려면
F5 키를 누릅니다.
폼에서
LastEditDate
열의 값을 변경하여 레코드를 업데이트한 다음 Save 단추를 클릭합니다.폼으로 돌아간 다음 Synchronize Now를 클릭합니다.
응용 프로그램 표와 서버 데이터베이스에서 업데이트를 확인합니다. 서버의 열 값이 클라이언트의 업데이트를 덮어썼습니다. 업데이트 과정은 다음과 같습니다.
Sync Framework가 클라이언트에서 행이 변경되었음을 식별합니다.
동기화 도중 행이 업로드되고 서버 데이터베이스의 테이블에 적용됩니다. 그러나 추적 열은 업데이트 명령문에 포함되지 않습니다. Sync Framework에서는 사실상 테이블에 대한 "더미 업데이트"를 수행합니다.
이제 클라이언트에 행이 반환되지만 서버에서 변경 내용을 선택하는 명령에는 추적 열이 포함되어 있습니다. 따라서 서버의 값이 클라이언트의 변경 내용을 덮어씁니다.
결론
이 연습에서는 기본적인 충돌 처리를 사용하여 양방향 동기화를 구성하고 클라이언트 데이터베이스에 있는 서버 추적 열로 인한 잠재적인 문제를 처리했습니다. partial 클래스를 사용하면 로컬 데이터베이스 캐시 코드를 다른 방법으로 크게 확장할 수 있습니다. 예를 들어 서버 데이터베이스에서 변경 내용을 선택하는 SQL 명령을 다시 정의하여 데이터를 필터링한 후 클라이언트로 다운로드할 수 있습니다. 우선 이 설명서의 방법 항목을 읽어 보고 응용 프로그램의 요구 사항에 맞게 동기화 코드를 추가하거나 변경하는 방법을 이해하는 것이 좋습니다. 자세한 내용은 일반적인 클라이언트 및 서버 동기화 태스크 프로그래밍을 참조하십시오.