Freigeben über


Erste Schritte: Client- und Serversynchronisierung

In diesem Thema wird eine Konsolenanwendung beschrieben, die ein erstes Dataset und anschließend aus derselben Tabelle einen Satz inkrementeller Änderungen herunterlädt. Die Anwendung ist unkompliziert, führt Sie aber in Code ein, der die Grundlage für die unterschiedlichsten Erläuterungen in der Sync Framework-Dokumentation bildet. Wenn Sie Architektur und Klassen für Client- und die Serversynchronisierung gelesen haben, sollten Ihnen die in der Anwendung verwendeten Hauptklassen bereits vertraut sein.

Eine Möglichkeit, sich diesem Thema zu nähern, besteht darin, einfach nur den Beispielcode durchzuarbeiten. Für ein besseres Verständnis empfiehlt es sich jedoch, die Anwendung auszuführen und sie in Aktion zu erleben. Stellen Sie vor dem Ausführen des Codes sicher, dass Folgendes installiert ist:

  • Sync Framework

    Die Anwendung benötigt Verweise auf Microsoft.Synchronization.Data.dll, Microsoft.Synchronization.Data.Server.dll und Microsoft.Synchronization.Data.SqlServerCe.dll.

  • SQL Server Compact Service Pack 1

    Die Anwendung benötigt einen Verweis auf System.Data.SqlServerCe.dll.

  • eine andere SQL Server-Version als SQL Server Compact, die als Serverdatenbank agiert

    Der Beispielcode verwendet in Verbindungszeichenfolgen localhost. Damit die Instanz von SQL Server Express verwendet werden kann, die mit Visual Studio installiert wird, muss localhost in .\sqlexpress geändert werden. Um einen Remoteserver zu verwenden, ändern Sie localhost in den entsprechenden Servernamen.

  • Die Sync Framework-Beispieldatenbanken. Führen Sie die beiden Skripts aus, die unter Setupskripts für Datenbankanbieter - Themen zur Vorgehensweise zur Verfügung stehen. Es empfiehlt sich, diese Skripts durchzugehen, um die Behandlung der Änderungsnachverfolgung in der Serverdatenbank zu verstehen.

Die Anwendung besteht aus sechs Klassen:

  • SampleSyncAgent. Diese Klasse ist von SyncAgent abgeleitet und enthält eine SyncTable.

  • SampleServerSyncProvider. Diese Klasse ist von DbServerSyncProvider abgeleitet und enthält den SyncAdapter.

  • SampleClientSyncProvider. Diese Klasse ist von SqlCeClientSyncProvider abgeleitet. In diesem Beispiel enthält diese Klasse nur eine Verbindungszeichenfolge zur Clientdatenbank.

  • SampleStats. Diese Klasse verwendet die Statistik, die vom SyncAgent zurückgegeben wird.

  • Program. Diese Klasse richtet die Synchronisierung ein und ruft Methoden der Utility-Klasse auf.

  • Utility. Diese Klasse behandelt alle Funktionen, die nicht direkt mit der Synchronisierung zusammenhängen, z. B. das Speichern der Verbindungszeichenfolge und das Vornehmen von Änderungen an der Serverdatenbank. In anderen Themen wird die vollständige Utility-Klasse verwendet. Die vollständige Klasse finden Sie in 'Utility'-Klasse für Datenbankanbieter - Themen zur Vorgehensweise.

Schlüsselbestandteile der API

Wir empfehlen, vor dem Ansehen des vollständigen Codebeispiels die folgenden Beispiele durchzugehen, in denen eine Reihe der wichtigsten Bestandteile der in dieser Anwendung verwendeten API gezeigt werden.

Erstellen einer "SyncTable"

Das folgende Codebeispiel erstellt ein SyncTable-Objekt für die Customer-Tabelle, legt die Synchronisierungsrichtung fest und gibt an, wie die Tabelle auf dem Client erstellt werden soll. Wenn, wie in diesem Fall, die Tabelle bereits in der Clientdatenbank vorhanden ist, wird sie bei der ersten Synchronisierung verworfen.

SyncTable customerSyncTable = new SyncTable("Customer");
customerSyncTable.CreationOption = TableCreationOption.DropExistingOrCreateNewTable;
customerSyncTable.SyncDirection = SyncDirection.DownloadOnly;
this.Configuration.SyncTables.Add(customerSyncTable);
Dim customerSyncTable As New SyncTable("Customer")
customerSyncTable.CreationOption = TableCreationOption.DropExistingOrCreateNewTable
customerSyncTable.SyncDirection = SyncDirection.DownloadOnly
Me.Configuration.SyncTables.Add(customerSyncTable)

Verwenden von "SqlSyncAdapterBuilder"

Mit jedem der in diesem Abschnitt erstellten Codebeispiele wird ein SyncAdapter für die Customer-Tabelle erstellt. Der Synchronisierungsadapter stellt die spezifischen Befehle für den Serversynchronisierungsanbieter bereit, die für die Interaktion mit der Serverdatenbank erforderlich sind. In dieser Anwendung wird der Synchronisierungsadapter mit SqlSyncAdapterBuilder erstellt. Im ersten Beispiel wird gezeigt, wie SqlSyncAdapterBuilder mithilfe eines benutzerdefinierten Systems zur Änderungsnachverfolgung verwendet wird. Im zweiten Beispiel wird gezeigt, wie SqlSyncAdapterBuilder mit der SQL Server-Änderungsnachverfolgung (verfügbar in SQL Server 2008) verwendet wird. Weitere Informationen zur Änderungsnachverfolgung finden Sie unter Änderungsnachverfolgung in der Serverdatenbank.

Informationen dazu, wie Sie ohne den Generator Befehle manuell erstellen können, finden Sie unter Vorgehensweise: Herunterladen inkrementeller Datenänderungen auf einen Client.

Verwenden eines benutzerdefinierten Systems für die Änderungsnachverfolgung

Geben Sie die folgenden Informationen für SqlSyncAdapterBuilder und SyncAdapter an, um ein benutzerdefiniertes System zur Änderungsnachverfolgung zu verwenden.

SqlSyncAdapterBuilder customerBuilder = new SqlSyncAdapterBuilder(serverConn);

customerBuilder.TableName = "Sales.Customer";
customerBuilder.TombstoneTableName = customerBuilder.TableName + "_Tombstone";
customerBuilder.SyncDirection = SyncDirection.DownloadOnly;
customerBuilder.CreationTrackingColumn = "InsertTimestamp";
customerBuilder.UpdateTrackingColumn = "UpdateTimestamp";
customerBuilder.DeletionTrackingColumn = "DeleteTimestamp";

SyncAdapter customerSyncAdapter = customerBuilder.ToSyncAdapter(false, false, false, false);
customerSyncAdapter.TableName = "Customer";
this.SyncAdapters.Add(customerSyncAdapter);
Dim customerBuilder As New SqlSyncAdapterBuilder(serverConn)

customerBuilder.TableName = "Sales.Customer"
customerBuilder.TombstoneTableName = customerBuilder.TableName + "_Tombstone"
customerBuilder.SyncDirection = SyncDirection.DownloadOnly
customerBuilder.CreationTrackingColumn = "InsertTimestamp"
customerBuilder.UpdateTrackingColumn = "UpdateTimestamp"
customerBuilder.DeletionTrackingColumn = "DeleteTimestamp"

Dim customerSyncAdapter As SyncAdapter = customerBuilder.ToSyncAdapter()
customerSyncAdapter.TableName = "Customer"
Me.SyncAdapters.Add(customerSyncAdapter)

Verwenden der Änderungsnachverfolgung von SQL Server

Geben Sie die folgenden Informationen für SqlSyncAdapterBuilder und SyncAdapter an, um die SQL Server-Änderungsnachverfolgung zu verwenden.

  • Der Name der Tabelle, die synchronisiert werden soll.

  • Richtung der Synchronisierung: Damit wird gesteuert, welche Befehle vom SqlSyncAdapterBuilder erstellt werden. Weitere Informationen zu Befehlen finden Sie unter Vorgehensweise: Angeben der Synchronisierungsart (Momentaufnahmen-, Nur-Download-, Nur-Upload- oder bidirektionale Synchronisierung).

  • Der Typ der Änderungsnachverfolgung, der verwendet werden soll. Standardmäßig ist Sync Framework auf die Festlegung von benutzerdefinierten Änderungsnachverfolgungsspalten eingestellt. In diesem Codebeispiel ist die SQL Server-Änderungsnachverfolgung angegeben.

  • Der Name des SyncAdapter. Dieser Name muss mit dem Namen der SyncTable übereinstimmen. Deshalb sollte der Name nicht den Schemanamen enthalten.

SqlSyncAdapterBuilder customerBuilder = new SqlSyncAdapterBuilder(serverConn);

customerBuilder.TableName = "Sales.Customer";
customerBuilder.ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking;

SyncAdapter customerSyncAdapter = customerBuilder.ToSyncAdapter();
customerSyncAdapter.TableName = "Customer";
this.SyncAdapters.Add(customerSyncAdapter);
Dim customerBuilder As New SqlSyncAdapterBuilder(serverConn)

customerBuilder.TableName = "Sales.Customer"
customerBuilder.ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking

Dim customerSyncAdapter As SyncAdapter = customerBuilder.ToSyncAdapter()
customerSyncAdapter.TableName = "Customer"
Me.SyncAdapters.Add(customerSyncAdapter)

Festlegen des neuen Ankerbefehls

Das folgende Codebeispiel gibt einen Befehl zum Abrufen eines neuen Ankerwerts vom Server an. Der Wert wird in der Clientdatenbank gespeichert und von den Befehlen verwendet, die Änderungen synchronisieren. Bei jeder Synchronisierung werden der neue Ankerwert und der letzte Ankerwert aus der vorherigen Synchronisierung verwendet. Alle Änderungen, die zwischen diesen beiden Grenzwerten erfolgt sind, werden synchronisiert.

In diesem Fall gibt MIN_ACTIVE_ROWVERSION einen Timestampwert aus einer SQL Server-Datenbank zurück. (MIN_ACTIVE_ROWVERSION wurde in SQL Server 2005 Service Pack 2 eingeführt.) Ein Timestampwert wird deshalb verwendet, weil die Nachverfolgungsspalten, die für den SqlSyncAdapterBuilder angegeben sind, Timestampwerte enthalten. Wenn die Nachverfolgungsspalten Datumswerte enthalten, können Sie anstelle von MIN_ACTIVE_ROWVERSION auch eine Funktion wie GETUTCDATE() verwenden. Weitere Informationen zu Ankern finden Sie unter Änderungsnachverfolgung in der Serverdatenbank.

Die SyncSession-Klasse enthält mehrere Zeichenfolgenkonstanten, die in Synchronisierungsbefehlen verwendet werden können. SyncNewReceivedAnchor ist eine dieser Konstanten. Sie können direkt in Ihren Abfragen auch das @sync_new_received_anchor-Literal verwenden.

SqlCommand selectNewAnchorCommand = new SqlCommand();
string newAnchorVariable = "@" + SyncSession.SyncNewReceivedAnchor;
selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = min_active_rowversion() - 1";
selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Timestamp);
selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output;
selectNewAnchorCommand.Connection = serverConn;
this.SelectNewAnchorCommand = selectNewAnchorCommand;
Dim selectNewAnchorCommand As New SqlCommand()
Dim newAnchorVariable As String = "@" + SyncSession.SyncNewReceivedAnchor
selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = min_active_rowversion() - 1"
selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Timestamp)
selectNewAnchorCommand.Parameters(newAnchorVariable).Direction = ParameterDirection.Output
selectNewAnchorCommand.Connection = serverConn
Me.SelectNewAnchorCommand = selectNewAnchorCommand

Aufrufen der Synchronisierungsmethode

Das folgende Codebeispiel instanziiert SampleSyncAgent und ruft die Synchronize-Methode auf. In der SampleSyncAgent-Klasse wird der SampleClientSyncProvider als LocalProvider und der SampleServerSyncProvider als RemoteProvider angegeben. Außerdem ist auch noch die bereits beschriebene Synchronisierungstabelle enthalten.

SampleSyncAgent sampleSyncAgent = new SampleSyncAgent();
SyncStatistics syncStatistics = sampleSyncAgent.Synchronize();
Dim sampleSyncAgent As New SampleSyncAgent()
Dim syncStatistics As SyncStatistics = sampleSyncAgent.Synchronize()

In der SampleStats-Klasse werden die von SyncAgent zurückgegebenen statistischen Daten verwendet, um dem Benutzer Feedback zur Synchronisierungssitzung zu geben. Weitere Informationen dazu finden Sie unter Vorgehensweise: Arbeiten mit Ereignissen und Programmgeschäftslogik.

Console.WriteLine("Start Time: " + syncStatistics.SyncStartTime);
Console.WriteLine("Total Changes Downloaded: " + syncStatistics.TotalChangesDownloaded);
Console.WriteLine("Complete Time: " + syncStatistics.SyncCompleteTime);
Console.WriteLine(String.Empty);
Console.WriteLine("Start Time: " & syncStatistics.SyncStartTime)
Console.WriteLine("Total Changes Downloaded: " & syncStatistics.TotalChangesDownloaded)
Console.WriteLine("Complete Time: " & syncStatistics.SyncCompleteTime)
Console.WriteLine(String.Empty)

Vollständige Codebeispiele

Nachdem Sie jetzt die Hauptbestandteile des Codes kennen, die an Synchronisierungen beteiligt sind, werden diese Bestandteile nun zu einer vollständigen Anwendung zusammengesetzt, die ausführlich erläutert wird. Wir empfehlen, dass Sie sich nach dem Ausführen dieser Anwendung mit den Themen im Abschnitt Programmieren von allgemeinen Client- und Serversynchronisierungsaufgaben zu beschäftigen. Dort finden Sie die gleichen Klassen wieder, die in den Codebeispielen in diesem Thema verwendet werden, wobei diese Klassen dort in umfangreicherer Form auf weitere Tabellen angewendet werden.

Vollständiges Beispiel zum Verwenden einer benutzerdefinierten Änderungsnachverfolgung

using System;
using System.IO;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Data;
using Microsoft.Synchronization.Data.Server;
using Microsoft.Synchronization.Data.SqlServerCe;

namespace Microsoft.Samples.Synchronization
{
    class Program
    {
        static void Main(string[] args)
        {

            //The SampleStats class handles information from the SyncStatistics
            //object that the Synchronize method returns.
            SampleStats sampleStats = new SampleStats();

            //Delete and re-create the database. The client synchronization
            //provider also enables you to create the client database 
            //if it does not exist.
            Utility.SetClientPassword();
            Utility.RecreateCompactDatabase();

            //Initial synchronization. Instantiate the SyncAgent
            //and call Synchronize.
            SampleSyncAgent sampleSyncAgent = new SampleSyncAgent();
            SyncStatistics syncStatistics = sampleSyncAgent.Synchronize();
            sampleStats.DisplayStats(syncStatistics, "initial");

            //Make changes on the server.
            Utility.MakeDataChangesOnServer();

            //Subsequent synchronization.
            syncStatistics = sampleSyncAgent.Synchronize();
            sampleStats.DisplayStats(syncStatistics, "subsequent");

            //Return server data back to its original state.
            Utility.CleanUpServer();

            //Exit.
            Console.Write("\nPress Enter to close the window.");
            Console.ReadLine();
        }
    }

    //Create a class that is derived from 
    //Microsoft.Synchronization.SyncAgent.
    public class SampleSyncAgent : SyncAgent
    {
        public SampleSyncAgent()
        {
            //Instantiate a client synchronization provider and specify it
            //as the local provider for this synchronization agent.
            this.LocalProvider = new SampleClientSyncProvider();

            //Instantiate a server synchronization provider and specify it
            //as the remote provider for this synchronization agent.
            this.RemoteProvider = new SampleServerSyncProvider();

            //Add the Customer table: specify a synchronization direction of
            //DownloadOnly.
            SyncTable customerSyncTable = new SyncTable("Customer");
            customerSyncTable.CreationOption = TableCreationOption.DropExistingOrCreateNewTable;
            customerSyncTable.SyncDirection = SyncDirection.DownloadOnly;
            this.Configuration.SyncTables.Add(customerSyncTable);
        }
    }

    //Create a class that is derived from 
    //Microsoft.Synchronization.Server.DbServerSyncProvider.
    public class SampleServerSyncProvider : DbServerSyncProvider
    {
        public SampleServerSyncProvider()
        {
            //Create a connection to the sample server database.
            Utility util = new Utility();
            SqlConnection serverConn = new SqlConnection(Utility.ConnStr_DbServerSync);
            this.Connection = serverConn;

            //Create a command to retrieve a new anchor value from
            //the server. In this case, we use a timestamp value
            //that is retrieved and stored in the client database.
            //During each synchronization, the new anchor value and
            //the last anchor value from the previous synchronization
            //are used: the set of changes between these upper and
            //lower bounds is synchronized.
            //
            //SyncSession.SyncNewReceivedAnchor is a string constant; 
            //you could also use @sync_new_received_anchor directly in 
            //your queries.
            SqlCommand selectNewAnchorCommand = new SqlCommand();
            string newAnchorVariable = "@" + SyncSession.SyncNewReceivedAnchor;
            selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = min_active_rowversion() - 1";
            selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Timestamp);
            selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output;
            selectNewAnchorCommand.Connection = serverConn;
            this.SelectNewAnchorCommand = selectNewAnchorCommand;


            //Create a SyncAdapter for the Customer table by using 
            //the SqlSyncAdapterBuilder:
            //  * Specify the base table and tombstone table names.
            //  * Specify the columns that are used to track when
            //    changes are made.
            //  * Specify download-only synchronization.
            //  * Call ToSyncAdapter to create the SyncAdapter.
            //  * Specify a name for the SyncAdapter that matches the
            //    the name specified for the corresponding SyncTable.
            //    Do not include the schema names (Sales in this case).

            SqlSyncAdapterBuilder customerBuilder = new SqlSyncAdapterBuilder(serverConn);

            customerBuilder.TableName = "Sales.Customer";
            customerBuilder.TombstoneTableName = customerBuilder.TableName + "_Tombstone";
            customerBuilder.SyncDirection = SyncDirection.DownloadOnly;
            customerBuilder.CreationTrackingColumn = "InsertTimestamp";
            customerBuilder.UpdateTrackingColumn = "UpdateTimestamp";
            customerBuilder.DeletionTrackingColumn = "DeleteTimestamp";

            SyncAdapter customerSyncAdapter = customerBuilder.ToSyncAdapter(false, false, false, false);
            customerSyncAdapter.TableName = "Customer";
            this.SyncAdapters.Add(customerSyncAdapter);

        }
    }

    //Create a class that is derived from 
    //Microsoft.Synchronization.Data.SqlServerCe.SqlCeClientSyncProvider.
    //You can just instantiate the provider directly and associate it
    //with the SyncAgent, but you could use this class to handle client 
    //provider events and other client-side processing.
    public class SampleClientSyncProvider : SqlCeClientSyncProvider
    {

        public SampleClientSyncProvider()
        {
            //Specify a connection string for the sample client database.
            Utility util = new Utility();
            this.ConnectionString = Utility.ConnStr_SqlCeClientSync;
        }
    }

    //Handle the statistics that are returned by the SyncAgent.
    public class SampleStats
    {
        public void DisplayStats(SyncStatistics syncStatistics, string syncType)
        {
            Console.WriteLine(String.Empty);
            if (syncType == "initial")
            {
                Console.WriteLine("****** Initial Synchronization ******");
            }
            else if (syncType == "subsequent")
            {
                Console.WriteLine("***** Subsequent Synchronization ****");
            }

            Console.WriteLine("Start Time: " + syncStatistics.SyncStartTime);
            Console.WriteLine("Total Changes Downloaded: " + syncStatistics.TotalChangesDownloaded);
            Console.WriteLine("Complete Time: " + syncStatistics.SyncCompleteTime);
            Console.WriteLine(String.Empty);

        }
    }

    public class Utility
    {

        private static string _clientPassword;

        //Get and set the client database password.
        public static string Password
        {
            get { return _clientPassword; }
            set { _clientPassword = value; }
        }

        //Have the user enter a password for the client database file.
        public static void SetClientPassword()
        {
            Console.WriteLine("Type a strong password for the client");
            Console.WriteLine("database, and then press Enter.");
            Utility.Password = Console.ReadLine();
        }

        //Return the client connection string with the password.
        public static string ConnStr_SqlCeClientSync
        {
            get { return @"Data Source='SyncSampleClient.sdf'; Password=" + Utility.Password; }
        }

        //Return the server connection string. 
        public static string ConnStr_DbServerSync
        {

            get { return @"Data Source=localhost; Initial Catalog=SyncSamplesDb; Integrated Security=True"; }

        }

        //Make server changes that are synchronized on the second 
        //synchronization.
        public static void MakeDataChangesOnServer()
        {
            int rowCount = 0;

            using (SqlConnection serverConn = new SqlConnection(Utility.ConnStr_DbServerSync))
            {
                SqlCommand sqlCommand = serverConn.CreateCommand();
                sqlCommand.CommandText =
                    "INSERT INTO Sales.Customer (CustomerName, SalesPerson, CustomerType) " +
                    "VALUES ('Cycle Mart', 'James Bailey', 'Retail') " +
                    
                    "UPDATE Sales.Customer " +
                    "SET  SalesPerson = 'James Bailey' " +
                    "WHERE CustomerName = 'Tandem Bicycle Store' " +

                    "DELETE FROM Sales.Customer WHERE CustomerName = 'Sharp Bikes'"; 
                
                serverConn.Open();
                rowCount = sqlCommand.ExecuteNonQuery();
                serverConn.Close();
            }

            Console.WriteLine("Rows inserted, updated, or deleted at the server: " + rowCount);
        }

        //Revert changes that were made during synchronization.
        public static void CleanUpServer()
        {
            using (SqlConnection serverConn = new SqlConnection(Utility.ConnStr_DbServerSync))
            {
                SqlCommand sqlCommand = serverConn.CreateCommand();
                sqlCommand.CommandType = CommandType.StoredProcedure;
                sqlCommand.CommandText = "usp_InsertSampleData";
                
                serverConn.Open();               
                sqlCommand.ExecuteNonQuery();
                serverConn.Close();
            }
        }

        //Delete the client database.
        public static void RecreateCompactDatabase()
        {
            using (SqlCeConnection clientConn = new SqlCeConnection(Utility.ConnStr_SqlCeClientSync))
            {
                if (File.Exists(clientConn.Database))
                {
                    File.Delete(clientConn.Database);
                }
            }

            SqlCeEngine sqlCeEngine = new SqlCeEngine(Utility.ConnStr_SqlCeClientSync);
            sqlCeEngine.CreateDatabase();
        }
    }
}
Imports System
Imports System.IO
Imports System.Text
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlServerCe
Imports Microsoft.Synchronization
Imports Microsoft.Synchronization.Data
Imports Microsoft.Synchronization.Data.Server
Imports Microsoft.Synchronization.Data.SqlServerCe

Class Program

    Shared Sub Main(ByVal args() As String)

        'The SampleStats class handles information from the SyncStatistics
        'object that the Synchronize method returns.
        Dim sampleStats As New SampleStats()

        'Delete and re-create the database. The client synchronization
        'provider also enables you to create the client database 
        'if it does not exist.
        Utility.SetClientPassword()
        Utility.RecreateCompactDatabase()

        'Initial synchronization. Instantiate the SyncAgent
        'and call Synchronize.
        Dim sampleSyncAgent As New SampleSyncAgent()
        Dim syncStatistics As SyncStatistics = sampleSyncAgent.Synchronize()
        sampleStats.DisplayStats(syncStatistics, "initial")

        'Make changes on the server.
        Utility.MakeDataChangesOnServer()

        'Subsequent synchronization.
        syncStatistics = sampleSyncAgent.Synchronize()
        sampleStats.DisplayStats(syncStatistics, "subsequent")

        'Return server data back to its original state.
        Utility.CleanUpServer()

        'Exit.
        Console.Write(vbLf + "Press Enter to close the window.")
        Console.ReadLine()

    End Sub 'Main
End Class 'Program

'Create a class that is derived from 
'Microsoft.Synchronization.SyncAgent.
Public Class SampleSyncAgent
    Inherits SyncAgent

    Public Sub New()
        'Instantiate a client synchronization provider and specify it
        'as the local provider for this synchronization agent.
        Me.LocalProvider = New SampleClientSyncProvider()

        'Instantiate a server synchronization provider and specify it
        'as the remote provider for this synchronization agent.
        Me.RemoteProvider = New SampleServerSyncProvider()

        'Add the Customer table: specify a synchronization direction of
        'DownloadOnly.
        Dim customerSyncTable As New SyncTable("Customer")
        customerSyncTable.CreationOption = TableCreationOption.DropExistingOrCreateNewTable
        customerSyncTable.SyncDirection = SyncDirection.DownloadOnly
        Me.Configuration.SyncTables.Add(customerSyncTable)

    End Sub 'New 
End Class 'SampleSyncAgent

'Create a class that is derived from 
'Microsoft.Synchronization.Server.DbServerSyncProvider.
Public Class SampleServerSyncProvider
    Inherits DbServerSyncProvider

    Public Sub New()
        'Create a connection to the sample server database.
        Dim util As New Utility()
        Dim serverConn As New SqlConnection(Utility.ConnStr_DbServerSync)
        Me.Connection = serverConn

        'Create a command to retrieve a new anchor value from
        'the server. In this case, we use a timestamp value
        'that is retrieved and stored in the client database.
        'During each synchronization, the new anchor value and
        'the last anchor value from the previous synchronization
        'are used: the set of changes between these upper and
        'lower bounds is synchronized.
        '
        'SyncSession.SyncNewReceivedAnchor is a string constant; 
        'you could also use @sync_new_received_anchor directly in 
        'your queries.
        Dim selectNewAnchorCommand As New SqlCommand()
        Dim newAnchorVariable As String = "@" + SyncSession.SyncNewReceivedAnchor
        selectNewAnchorCommand.CommandText = "SELECT " + newAnchorVariable + " = min_active_rowversion() - 1"
        selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Timestamp)
        selectNewAnchorCommand.Parameters(newAnchorVariable).Direction = ParameterDirection.Output
        selectNewAnchorCommand.Connection = serverConn
        Me.SelectNewAnchorCommand = selectNewAnchorCommand

        'Create a SyncAdapter for the Customer table by using 
        'the SqlSyncAdapterBuilder:
        '  * Specify the base table and tombstone table names.
        '  * Specify the columns that are used to track when
        '    changes are made.
        '  * Specify download-only synchronization.
        '  * Call ToSyncAdapter to create the SyncAdapter.
        '  * Specify a name for the SyncAdapter that matches the
        '    the name specified for the corresponding SyncTable.
        '    Do not include the schema names (Sales in this case).
        Dim customerBuilder As New SqlSyncAdapterBuilder(serverConn)

        customerBuilder.TableName = "Sales.Customer"
        customerBuilder.TombstoneTableName = customerBuilder.TableName + "_Tombstone"
        customerBuilder.SyncDirection = SyncDirection.DownloadOnly
        customerBuilder.CreationTrackingColumn = "InsertTimestamp"
        customerBuilder.UpdateTrackingColumn = "UpdateTimestamp"
        customerBuilder.DeletionTrackingColumn = "DeleteTimestamp"

        Dim customerSyncAdapter As SyncAdapter = customerBuilder.ToSyncAdapter()
        customerSyncAdapter.TableName = "Customer"
        Me.SyncAdapters.Add(customerSyncAdapter)

    End Sub 'New
End Class 'SampleServerSyncProvider

'Create a class that is derived from 
'Microsoft.Synchronization.Data.SqlServerCe.SqlCeClientSyncProvider.
'You can just instantiate the provider directly and associate it
'with the SyncAgent, but you could use this class to handle client 
'provider events and other client-side processing.
Public Class SampleClientSyncProvider
    Inherits SqlCeClientSyncProvider


    Public Sub New()
        'Specify a connection string for the sample client database.
        Dim util As New Utility()
        Me.ConnectionString = Utility.ConnStr_SqlCeClientSync

    End Sub 'New
End Class 'SampleClientSyncProvider

'Handle the statistics that are returned by the SyncAgent.
Public Class SampleStats

    Public Sub DisplayStats(ByVal syncStatistics As SyncStatistics, ByVal syncType As String)
        Console.WriteLine(String.Empty)
        If syncType = "initial" Then
            Console.WriteLine("****** Initial Synchronization ******")
        ElseIf syncType = "subsequent" Then
            Console.WriteLine("***** Subsequent Synchronization ****")
        End If

        Console.WriteLine("Start Time: " & syncStatistics.SyncStartTime)
        Console.WriteLine("Total Changes Downloaded: " & syncStatistics.TotalChangesDownloaded)
        Console.WriteLine("Complete Time: " & syncStatistics.SyncCompleteTime)
        Console.WriteLine(String.Empty)

    End Sub 'DisplayStats 
End Class 'SampleStats


Public Class Utility

    Private Shared _clientPassword As String

    'Get and set the client database password.
    Public Shared Property Password() As String
        Get
            Return _clientPassword
        End Get
        Set(ByVal value As String)
            _clientPassword = value
        End Set
    End Property

    'Have the user enter a password for the client database file.
    Public Shared Sub SetClientPassword()
        Console.WriteLine("Type a strong password for the client")
        Console.WriteLine("database, and then press Enter.")
        Utility.Password = Console.ReadLine()

    End Sub 'SetClientPassword

    'Return the client connection string with the password.
    Public Shared ReadOnly Property ConnStr_SqlCeClientSync() As String
        Get
            Return "Data Source='SyncSampleClient.sdf'; Password=" + Utility.Password
        End Get
    End Property

    'Return the server connection string. 
    Public Shared ReadOnly Property ConnStr_DbServerSync() As String

        Get
            Return "Data Source=localhost; Initial Catalog=SyncSamplesDb; Integrated Security=True"
        End Get
    End Property


    'Make server changes that are synchronized on the second 
    'synchronization.
    Public Shared Sub MakeDataChangesOnServer()
        Dim rowCount As Integer = 0

        Dim serverConn As New SqlConnection(Utility.ConnStr_DbServerSync)
        Try
            Dim sqlCommand As SqlCommand = serverConn.CreateCommand()
            sqlCommand.CommandText = _
                "INSERT INTO Sales.Customer (CustomerName, SalesPerson, CustomerType) " _
              & "VALUES ('Cycle Mart', 'James Bailey', 'Retail') " _
              & "UPDATE Sales.Customer " _
              & "SET  SalesPerson = 'James Bailey' " _
              & "WHERE CustomerName = 'Tandem Bicycle Store' " _
              & "DELETE FROM Sales.Customer WHERE CustomerName = 'Sharp Bikes'"
            serverConn.Open()
            rowCount = sqlCommand.ExecuteNonQuery()
            serverConn.Close()
        Finally
            serverConn.Dispose()
        End Try

        Console.WriteLine("Rows inserted, updated, or deleted at the server: " & rowCount)

    End Sub 'MakeDataChangesOnServer


    'Revert changes that were made during synchronization.
    Public Shared Sub CleanUpServer()
        Dim serverConn As New SqlConnection(Utility.ConnStr_DbServerSync)
        Try
            Dim sqlCommand As SqlCommand = serverConn.CreateCommand()
            sqlCommand.CommandType = CommandType.StoredProcedure
            sqlCommand.CommandText = "usp_InsertSampleData"

            serverConn.Open()
            sqlCommand.ExecuteNonQuery()
            serverConn.Close()
        Finally
            serverConn.Dispose()
        End Try

    End Sub 'CleanUpServer


    'Delete the client database.
    Public Shared Sub RecreateCompactDatabase()
        Dim clientConn As New SqlCeConnection(Utility.ConnStr_SqlCeClientSync)
        Try
            If File.Exists(clientConn.Database) Then
                File.Delete(clientConn.Database)
            End If
        Finally
            clientConn.Dispose()
        End Try

        Dim sqlCeEngine As New SqlCeEngine(Utility.ConnStr_SqlCeClientSync)
        sqlCeEngine.CreateDatabase()

    End Sub 'RecreateClientDatabase
End Class 'Utility

Vollständiges Beispiel zum Verwenden einer SQL Server-Änderungsnachverfolgung

using System;
using System.IO;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlServerCe;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Data;
using Microsoft.Synchronization.Data.Server;
using Microsoft.Synchronization.Data.SqlServerCe;

namespace Microsoft.Samples.Synchronization
{
    class Program
    {
        static void Main(string[] args)
        {
            
            //The SampleStats class handles information from the SyncStatistics
            //object that the Synchronize method returns.
            SampleStats sampleStats = new SampleStats();

            //Delete and re-create the database. The client synchronization
            //provider also enables you to create the client database 
            //if it does not exist.
            Utility.SetClientPassword();
            Utility.RecreateCompactDatabase();

            //Initial synchronization. Instantiate the SyncAgent
            //and call Synchronize.
            SampleSyncAgent sampleSyncAgent = new SampleSyncAgent();
            SyncStatistics syncStatistics = sampleSyncAgent.Synchronize();
            sampleStats.DisplayStats(syncStatistics, "initial");

            //Make changes on the server.
            Utility.MakeDataChangesOnServer();

            //Subsequent synchronization.
            syncStatistics = sampleSyncAgent.Synchronize();
            sampleStats.DisplayStats(syncStatistics, "subsequent");

            //Return server data back to its original state.
            Utility.CleanUpServer();

            //Exit.
            Console.Write("\nPress Enter to close the window.");
            Console.ReadLine();
        }
    }

    //Create a class that is derived from 
    //Microsoft.Synchronization.SyncAgent.
    public class SampleSyncAgent : SyncAgent
    {
        public SampleSyncAgent()
        {
            //Instantiate a client synchronization provider and specify it
            //as the local provider for this synchronization agent.
            this.LocalProvider = new SampleClientSyncProvider();

            //Instantiate a server synchronization provider and specify it
            //as the remote provider for this synchronization agent.
            this.RemoteProvider = new SampleServerSyncProvider();

            //Add the Customer table: specify a synchronization direction of
            //DownloadOnly.
            SyncTable customerSyncTable = new SyncTable("Customer");
            customerSyncTable.CreationOption = TableCreationOption.DropExistingOrCreateNewTable;
            customerSyncTable.SyncDirection = SyncDirection.DownloadOnly;
            this.Configuration.SyncTables.Add(customerSyncTable);
        }
    }

    //Create a class that is derived from 
    //Microsoft.Synchronization.Server.DbServerSyncProvider.
    public class SampleServerSyncProvider : DbServerSyncProvider
    {
        public SampleServerSyncProvider()
        {
            //Create a connection to the sample server database.
            Utility util = new Utility();
            SqlConnection serverConn = new SqlConnection(Utility.ConnStr_DbServerSync);
            this.Connection = serverConn;

            //Create a command to retrieve a new anchor value from
            //the server. In this case, we use a timestamp value
            //that is retrieved and stored in the client database.
            //During each synchronization, the new anchor value and
            //the last anchor value from the previous synchronization
            //are used: the set of changes between these upper and
            //lower bounds is synchronized.
            //
            //SyncSession.SyncNewReceivedAnchor is a string constant; 
            //you could also use @sync_new_received_anchor directly in 
            //your queries.
            SqlCommand selectNewAnchorCommand = new SqlCommand();
            string newAnchorVariable = "@" + SyncSession.SyncNewReceivedAnchor;
            selectNewAnchorCommand.CommandText =
                "SELECT " + newAnchorVariable + " = change_tracking_current_version()";
            selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.BigInt);
            selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output;
            selectNewAnchorCommand.Connection = serverConn;
            this.SelectNewAnchorCommand = selectNewAnchorCommand;


            //Create a SyncAdapter for the Customer table by using 
            //the SqlSyncAdapterBuilder:
            //  * Specify the base table name.
            //  * Specify that the server uses SQL Server change tracking.
            //  * Specify download-only synchronization.
            //  * Call ToSyncAdapter to create the SyncAdapter.
            //  * Specify a name for the SyncAdapter that matches the
            //    the name specified for the corresponding SyncTable.
            //    Do not include the schema names (Sales in this case).

            SqlSyncAdapterBuilder customerBuilder = new SqlSyncAdapterBuilder(serverConn);

            customerBuilder.TableName = "Sales.Customer";
            customerBuilder.ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking;

            SyncAdapter customerSyncAdapter = customerBuilder.ToSyncAdapter();
            customerSyncAdapter.TableName = "Customer";
            this.SyncAdapters.Add(customerSyncAdapter);

        }
    }

    //Create a class that is derived from 
    //Microsoft.Synchronization.Data.SqlServerCe.SqlCeClientSyncProvider.
    //You can just instantiate the provider directly and associate it
    //with the SyncAgent, but you could use this class to handle client 
    //provider events and other client-side processing.
    public class SampleClientSyncProvider : SqlCeClientSyncProvider
    {

        public SampleClientSyncProvider()
        {
            //Specify a connection string for the sample client database.
            Utility util = new Utility();
            this.ConnectionString = Utility.ConnStr_SqlCeClientSync;
        }
    }

    //Handle the statistics that are returned by the SyncAgent.
    public class SampleStats
    {
        public void DisplayStats(SyncStatistics syncStatistics, string syncType)
        {
            Console.WriteLine(String.Empty);
            if (syncType == "initial")
            {
                Console.WriteLine("****** Initial Synchronization ******");
            }
            else if (syncType == "subsequent")
            {
                Console.WriteLine("***** Subsequent Synchronization ****");
            }

            Console.WriteLine("Start Time: " + syncStatistics.SyncStartTime);
            Console.WriteLine("Total Changes Downloaded: " + syncStatistics.TotalChangesDownloaded);
            Console.WriteLine("Complete Time: " + syncStatistics.SyncCompleteTime);
            Console.WriteLine(String.Empty);

        }
    }

    public class Utility
    {

        private static string _clientPassword;

        //Get and set the client database password.
        public static string Password
        {
            get { return _clientPassword; }
            set { _clientPassword = value; }
        }

        //Have the user enter a password for the client database file.
        public static void SetClientPassword()
        {
            Console.WriteLine("Type a strong password for the client");
            Console.WriteLine("database, and then press Enter.");
            Utility.Password = Console.ReadLine();
        }

        //Return the client connection string with the password.
        public static string ConnStr_SqlCeClientSync
        {
            get { return @"Data Source='SyncSampleClient.sdf'; Password=" + Utility.Password; }
        }

        //Return the server connection string. 
        public static string ConnStr_DbServerSync
        {

            get { return @"Data Source=localhost; Initial Catalog=SyncSamplesDb_ChangeTracking; Integrated Security=True"; }

        }

        //Make server changes that are synchronized on the second 
        //synchronization.
        public static void MakeDataChangesOnServer()
        {
            int rowCount = 0;

            using (SqlConnection serverConn = new SqlConnection(Utility.ConnStr_DbServerSync))
            {
                SqlCommand sqlCommand = serverConn.CreateCommand();
                sqlCommand.CommandText =
                    "INSERT INTO Sales.Customer (CustomerName, SalesPerson, CustomerType) " +
                    "VALUES ('Cycle Mart', 'James Bailey', 'Retail') " +

                    "UPDATE Sales.Customer " +
                    "SET  SalesPerson = 'James Bailey' " +
                    "WHERE CustomerName = 'Tandem Bicycle Store' " +

                    "DELETE FROM Sales.Customer WHERE CustomerName = 'Sharp Bikes'";

                serverConn.Open();
                rowCount = sqlCommand.ExecuteNonQuery();
                serverConn.Close();
            }

            Console.WriteLine("Rows inserted, updated, or deleted at the server: " + rowCount);
        }

        //Revert changes that were made during synchronization.
        public static void CleanUpServer()
        {
            using (SqlConnection serverConn = new SqlConnection(Utility.ConnStr_DbServerSync))
            {
                SqlCommand sqlCommand = serverConn.CreateCommand();
                sqlCommand.CommandType = CommandType.StoredProcedure;
                sqlCommand.CommandText = "usp_InsertSampleData";

                serverConn.Open();
                sqlCommand.ExecuteNonQuery();
                serverConn.Close();
            }
        }

        //Delete the client database.
        public static void RecreateCompactDatabase()
        {
            using (SqlCeConnection clientConn = new SqlCeConnection(Utility.ConnStr_SqlCeClientSync))
            {
                if (File.Exists(clientConn.Database))
                {
                    File.Delete(clientConn.Database);
                }
            }

            SqlCeEngine sqlCeEngine = new SqlCeEngine(Utility.ConnStr_SqlCeClientSync);
            sqlCeEngine.CreateDatabase();
        }
    }
}
Imports System
Imports System.IO
Imports System.Text
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.SqlServerCe
Imports Microsoft.Synchronization
Imports Microsoft.Synchronization.Data
Imports Microsoft.Synchronization.Data.Server
Imports Microsoft.Synchronization.Data.SqlServerCe

Class Program

    Shared Sub Main(ByVal args() As String)

        'The SampleStats class handles information from the SyncStatistics
        'object that the Synchronize method returns.
        Dim sampleStats As New SampleStats()

        'Delete and re-create the database. The client synchronization
        'provider also enables you to create the client database 
        'if it does not exist.
        Utility.SetClientPassword()
        Utility.RecreateCompactDatabase()

        'Initial synchronization. Instantiate the SyncAgent
        'and call Synchronize.
        Dim sampleSyncAgent As New SampleSyncAgent()
        Dim syncStatistics As SyncStatistics = sampleSyncAgent.Synchronize()
        sampleStats.DisplayStats(syncStatistics, "initial")

        'Make changes on the server.
        Utility.MakeDataChangesOnServer()

        'Subsequent synchronization.
        syncStatistics = sampleSyncAgent.Synchronize()
        sampleStats.DisplayStats(syncStatistics, "subsequent")

        'Return server data back to its original state.
        Utility.CleanUpServer()

        'Exit.
        Console.Write(vbLf + "Press Enter to close the window.")
        Console.ReadLine()

    End Sub 'Main
End Class 'Program

'Create a class that is derived from 
'Microsoft.Synchronization.SyncAgent.
Public Class SampleSyncAgent
    Inherits SyncAgent

    Public Sub New()
        'Instantiate a client synchronization provider and specify it
        'as the local provider for this synchronization agent.
        Me.LocalProvider = New SampleClientSyncProvider()

        'Instantiate a server synchronization provider and specify it
        'as the remote provider for this synchronization agent.
        Me.RemoteProvider = New SampleServerSyncProvider()

        'Add the Customer table: specify a synchronization direction of
        'DownloadOnly.
        Dim customerSyncTable As New SyncTable("Customer")
        customerSyncTable.CreationOption = TableCreationOption.DropExistingOrCreateNewTable
        customerSyncTable.SyncDirection = SyncDirection.DownloadOnly
        Me.Configuration.SyncTables.Add(customerSyncTable)

    End Sub 'New 
End Class 'SampleSyncAgent

'Create a class that is derived from 
'Microsoft.Synchronization.Server.DbServerSyncProvider.
Public Class SampleServerSyncProvider
    Inherits DbServerSyncProvider

    Public Sub New()
        'Create a connection to the sample server database.
        Dim util As New Utility()
        Dim serverConn As New SqlConnection(Utility.ConnStr_DbServerSync)
        Me.Connection = serverConn

        'Create a command to retrieve a new anchor value from
        'the server. In this case, we use a timestamp value
        'that is retrieved and stored in the client database.
        'During each synchronization, the new anchor value and
        'the last anchor value from the previous synchronization
        'are used: the set of changes between these upper and
        'lower bounds is synchronized.
        '
        'SyncSession.SyncNewReceivedAnchor is a string constant; 
        'you could also use @sync_new_received_anchor directly in 
        'your queries.
        Dim selectNewAnchorCommand As New SqlCommand()
        Dim newAnchorVariable As String = "@" + SyncSession.SyncNewReceivedAnchor
        With selectNewAnchorCommand
            .CommandText = _
                "SELECT " + newAnchorVariable + " = change_tracking_current_version()"
            .Parameters.Add(newAnchorVariable, SqlDbType.BigInt)
            .Parameters(newAnchorVariable).Direction = ParameterDirection.Output
            .Connection = serverConn
        End With
        Me.SelectNewAnchorCommand = selectNewAnchorCommand

        'Create a SyncAdapter for the Customer table by using 
        'the SqlSyncAdapterBuilder:
        '  * Specify the base table names.
        '  * Specify that the server uses SQL Server change tracking.
        '  * Specify download-only synchronization.
        '  * Call ToSyncAdapter to create the SyncAdapter.
        '  * Specify a name for the SyncAdapter that matches the
        '    the name specified for the corresponding SyncTable.
        '    Do not include the schema names (Sales in this case).
        Dim customerBuilder As New SqlSyncAdapterBuilder(serverConn)

        customerBuilder.TableName = "Sales.Customer"
        customerBuilder.ChangeTrackingType = ChangeTrackingType.SqlServerChangeTracking

        Dim customerSyncAdapter As SyncAdapter = customerBuilder.ToSyncAdapter()
        customerSyncAdapter.TableName = "Customer"
        Me.SyncAdapters.Add(customerSyncAdapter)

    End Sub 'New
End Class 'SampleServerSyncProvider

'Create a class that is derived from 
'Microsoft.Synchronization.Data.SqlServerCe.SqlCeClientSyncProvider.
'You can just instantiate the provider directly and associate it
'with the SyncAgent, but you could use this class to handle client 
'provider events and other client-side processing.
Public Class SampleClientSyncProvider
    Inherits SqlCeClientSyncProvider


    Public Sub New()
        'Specify a connection string for the sample client database.
        Dim util As New Utility()
        Me.ConnectionString = Utility.ConnStr_SqlCeClientSync

    End Sub 'New
End Class 'SampleClientSyncProvider

'Handle the statistics that are returned by the SyncAgent.
Public Class SampleStats

    Public Sub DisplayStats(ByVal syncStatistics As SyncStatistics, ByVal syncType As String)
        Console.WriteLine(String.Empty)
        If syncType = "initial" Then
            Console.WriteLine("****** Initial Synchronization ******")
        ElseIf syncType = "subsequent" Then
            Console.WriteLine("***** Subsequent Synchronization ****")
        End If

        Console.WriteLine("Start Time: " & syncStatistics.SyncStartTime)
        Console.WriteLine("Total Changes Downloaded: " & syncStatistics.TotalChangesDownloaded)
        Console.WriteLine("Complete Time: " & syncStatistics.SyncCompleteTime)
        Console.WriteLine(String.Empty)

    End Sub 'DisplayStats 
End Class 'SampleStats


Public Class Utility

    Private Shared _clientPassword As String

    'Get and set the client database password.
    Public Shared Property Password() As String
        Get
            Return _clientPassword
        End Get
        Set(ByVal value As String)
            _clientPassword = value
        End Set
    End Property

    'Have the user enter a password for the client database file.
    Public Shared Sub SetClientPassword()
        Console.WriteLine("Type a strong password for the client")
        Console.WriteLine("database, and then press Enter.")
        Utility.Password = Console.ReadLine()

    End Sub 'SetClientPassword

    'Return the client connection string with the password.
    Public Shared ReadOnly Property ConnStr_SqlCeClientSync() As String
        Get
            Return "Data Source='SyncSampleClient.sdf'; Password=" + Utility.Password
        End Get
    End Property

    'Return the server connection string. 
    Public Shared ReadOnly Property ConnStr_DbServerSync() As String
        Get
            Return "Data Source=localhost; Initial Catalog=SyncSamplesDb_ChangeTracking; Integrated Security=True"
        End Get
    End Property


    'Make server changes that are synchronized on the second 
    'synchronization.
    Public Shared Sub MakeDataChangesOnServer()
        Dim rowCount As Integer = 0

        Dim serverConn As New SqlConnection(Utility.ConnStr_DbServerSync)
        Try
            Dim sqlCommand As SqlCommand = serverConn.CreateCommand()
            sqlCommand.CommandText = _
                "INSERT INTO Sales.Customer (CustomerName, SalesPerson, CustomerType) " _
              & "VALUES ('Cycle Mart', 'James Bailey', 'Retail') " _
              & "UPDATE Sales.Customer " _
              & "SET  SalesPerson = 'James Bailey' " _
              & "WHERE CustomerName = 'Tandem Bicycle Store' " _
              & "DELETE FROM Sales.Customer WHERE CustomerName = 'Sharp Bikes'"
            serverConn.Open()
            rowCount = sqlCommand.ExecuteNonQuery()
            serverConn.Close()
        Finally
            serverConn.Dispose()
        End Try

        Console.WriteLine("Rows inserted, updated, or deleted at the server: " & rowCount)

    End Sub 'MakeDataChangesOnServer


    'Revert changes that were made during synchronization.
    Public Shared Sub CleanUpServer()
        Dim serverConn As New SqlConnection(Utility.ConnStr_DbServerSync)
        Try
            Dim sqlCommand As SqlCommand = serverConn.CreateCommand()
            sqlCommand.CommandType = CommandType.StoredProcedure
            sqlCommand.CommandText = "usp_InsertSampleData"

            serverConn.Open()
            sqlCommand.ExecuteNonQuery()
            serverConn.Close()
        Finally
            serverConn.Dispose()
        End Try

    End Sub 'CleanUpServer


    'Delete the client database.
    Public Shared Sub RecreateCompactDatabase()
        Dim clientConn As New SqlCeConnection(Utility.ConnStr_SqlCeClientSync)
        Try
            If File.Exists(clientConn.Database) Then
                File.Delete(clientConn.Database)
            End If
        Finally
            clientConn.Dispose()
        End Try

        Dim sqlCeEngine As New SqlCeEngine(Utility.ConnStr_SqlCeClientSync)
        sqlCeEngine.CreateDatabase()

    End Sub 'RecreateClientDatabase
End Class 'Utility

Siehe auch

Konzepte

Architektur und Klassen für die Client- und Serversynchronisierung
Offlineszenarien