Freigeben über


Exemplarische Vorgehensweise: Erweitern des Caches für lokale Datenbanken für die Unterstützung bidirektionaler Synchronisierung

Aktualisiert: Juli 2008

In Visual Studio 2008 wird mit dem Cache für lokale Datenbanken eine SQL Server Compact 3.5-Datenbank und ein Satz partieller Klassen konfiguriert, mit denen Microsoft Synchronization Services für ADO.NET aktiviert wird. Da Visual Studio partielle Klassen generiert, können Sie Code für zusätzliche Synchronisierungsfunktionen hinzuzufügen und dennoch Einstellungen im Dialogfeld Datensychronisation konfigurieren anzeigen und ändern. Weitere Informationen zu partiellen Klassen finden Sie unter Gewusst wie: Aufteilen einer Klasse in partielle Klassen.

In der Standardeinstellung kann Synchronization Services mit dem Dialogfeld Datensynchronisierung konfigurieren nur für das Herunterladen konfiguriert werden. Das bedeutet, dass beim Aufruf von Synchronize() nach der Konfiguration der Datensynchronisation nur Änderungen vom Server zur Clientdatenbank heruntergeladen werden. Eine weit verbreitete Möglichkeit, den Synchronisierungscode zu erweitern, ist die Konfiguration bidirektionaler Synchronisierung. Damit können Änderungen vom Client zum Server hochgeladen werden. Zum Aktivieren der bidirektionalen Synchronisierung wird empfohlen, den generierten Code auf die folgende Weise zu erweitern:

  • Legen Sie die Synchronisierungsrichtung auf bidirektional fest.

  • Fügen Sie Code zur Behandlung von Synchronisierungskonflikten hinzu.

  • Entfernen Sie Servernachverfolgungsspalten aus den Synchronisierungsbefehlen.

Vorbereitungsmaßnahmen

Bevor Sie mit dieser exemplarische Vorgehensweise beginnen, müssen Sie Exemplarische Vorgehensweise: Erstellen einer gelegentlich verbundenen Anwendung abschließen. Im Verlauf dieser exemplarische Vorgehensweise erstellen Sie ein Projekt, das ein Cache für lokale Datenbanken und eine Windows Forms-Anwendung enthält, mit der Änderungen aus der Northwind-Kundentabelle in eine SQL Server Compact-Datenbank heruntergeladen werden können. Im Folgenden wird die Projektmappe für diese exemplarische Vorgehensweise geladen und die bidirektionale Funktionalität hinzugefügt.

Hinweis:

Ihr Computer zeigt möglicherweise für einige der Elemente der Visual Studio-Benutzeroberfläche in der folgenden Anleitung andere Namen oder Standorte an. Diese Elemente sind von der jeweiligen Visual Studio-Version und den verwendeten Einstellungen abhängig. Weitere Informationen finden Sie unter Visual Studio-Einstellungen.

So öffnen Sie die OCSWalkthrough-Projektmappe

  1. Öffnen Sie Visual Studio.

  2. Öffnen Sie im Menü Datei eine vorhandene Projektmappe oder ein Projekt, und suchen Sie die Projektmappe "OCSWalkthrough". Dies ist die Datei OCSWalkthrough.sln.

Festlegen der Synchronisierungsrichtung

Im Dialogfeld Datensynchronisierung konfigurieren können Sie die SyncDirection()-Eigenschaft entweder auf DownloadOnly() oder auf Snapshot() festlegen. Um die bidirektionale Synchronisierung zu aktivieren, legen Sie für jede Tabelle, für die Sie das Hochladen von Änderungen aktivieren möchten, die SyncDirection()-Eigenschaft auf Bidirectional() fest.

So legen Sie Synchronisierungsrichtung fest

  1. Klicken Sie mit der rechten Maustaste auf NorthwindCache.sync, und klicken Sie auf Code anzeigen. Wenn Sie dies zum ersten Mal ausführen, erstellt Visual Studio im Projektmappen-Explorer eine NorthwindCache-Datei unter dem Knoten NorthwindCache.sync. Diese Datei enthält die partielle Klasse NorthwindCacheSyncAgent. Sie können nach Bedarf weitere Klassen hinzufügen.

  2. Fügen Sie in der NorthwindCache-Klassendatei Code hinzu. Die NorthwindCacheSyncAgent.OnInitialized()-Methode sollte wie folgt aussehen:

    partial void OnInitialized()
    {
        this.Customers.SyncDirection = 
        Microsoft.Synchronization.Data.SyncDirection.Bidirectional;
    }
    
    Private Sub OnInitialized()
        Me.Customers.SyncDirection = 
        Microsoft.Synchronization.Data.SyncDirection.Bidirectional
    End Sub
    
  3. Öffnen Sie Form1 im Code-Editor.

  4. Ändern Sie in der Datei Form1 die Codezeile im SynchronizeButton_Click-Ereignishandler, damit Statistiken für das Hoch- und Herunterladen hinzugefügt werden:

    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)
    

Testen der Anwendung

Die Anwendung ist nun so konfiguriert, dass bei der Synchronisierung sowohl hoch- als auch heruntergeladen wird.

So testen Sie die Anwendung

  1. Drücken Sie die Taste F5.

  2. Aktualisieren Sie im Formular einen Datensatz, und klicken Sie dann auf die Schaltfläche Speichern (das Datenträgersymbol auf der Symbolleiste).

  3. Klicken Sie auf Jetzt synchronisieren.

  4. Ein Meldungsfeld wird angezeigt, das Informationen über synchronisierte Datensätze enthält. Die Statistik zeigt, dass eine Zeile hoch- und eine heruntergeladen wurde, obwohl keine Änderungen auf dem Server vorgenommen wurden. Das zusätzliche Herunterladen tritt auf, weil Änderungen des Clients, nachdem sie für den Server übernommen wurden, an den Client zurückgegeben werden. Weitere Informationen finden Sie unter "Determining Which Client Made a Data Change" in How to: Use a Custom Change Tracking System.

  5. Klicken Sie auf OK, um das Meldungsfeld zu schließen, beenden Sie jedoch nicht die Ausführung der Anwendung.

Um einen Konflikt (Parallelitätsverletzung) während der Synchronisierung hervorzurufen, ändern Sie nun denselben Datensatz sowohl auf dem Client als auch auf dem Server.

So testen Sie die Anwendung und erzwingen einen Konflikt

  1. Aktualisieren Sie im Formular einen Datensatz, und klicken Sie dann auf die Schaltfläche Speichern.

  2. Verwenden Sie während die Anwendung ausgeführt wird den Server-Explorer/Datenbank-Explorer (oder ein anderes Tool zur Datenbankverwaltung), um eine Verbindung mit der Serverdatenbank herzustellen.

  3. Um das Standardverhalten für Konfliktauflösung in Server-Explorer/Datenbank-Explorer zu veranschaulichen, aktualisieren Sie den bereits im Formular aktualisierten Datensatz, ändern ihn jedoch in einen anderen Wert und übernehmen die Änderung. (Bewegen Sie den Mauszeiger von der geänderten Zeile weg.)

  4. Wechseln Sie zum Formular zurück, und klicken Sie dann auf Jetzt synchronisieren.

  5. Überprüfen Sie die Aktualisierung im Raster der Anwendung und der Serverdatenbank. Beachten Sie, dass die auf dem Server vorgenommene Aktualisierung die Aktualisierung des Clients überschrieben hat. Informationen zum Ändern dieses Konfliktauflösungsverhaltens finden Sie im nächsten Abschnitt dieses Themas "Hinzufügen von Code zum Behandeln von Synchronisierungskonflikten".

Hinzufügen von Code zum Behandeln von Synchronisierungskonflikten

In Synchronization Services liegt dann ein Konflikt für eine Zeile vor, wenn sie zwischen Synchronisierungen sowohl auf dem Client als auch auf dem Server geändert wurde. Synchronization Services stellt einen Satz von Features zum Erkennen und Auflösen von Konflikten bereit. In diesem Abschnitt wird die grundlegende Behandlung für Konflikte hinzugefügt, in denen dieselbe Zeile sowohl auf dem Client als auch auf dem Server aktualisiert wurde. Zu anderen Arten von Konflikten zählen z. B. eine Zeile, die in der einen Datenbank gelöscht und in einer anderen aktualisiert wurde, und Zeilen, für die doppelte Primärschlüssel in beide Datenbanken eingefügt wurden. Weitere Informationen über das Erkennen und Auflösen von Konflikten finden Sie unter How to: Handle Data Conflicts and Errors.

Hinweis:

Im Beispielcode wird ein grundlegendes Beispiel für die Konfliktbehandlung bereitgestellt. Die Methode, mit der Sie Konflikte behandeln, ist von den Anforderungen der Anwendung und der Geschäftslogik abhängig.

Fügen Sie Code hinzu, mit dem das ApplyChangeFailed-Ereignis des Servers und das ApplyChangeFailed-Ereignis des Clients behandelt wird. Diese Ereignisse werden ausgelöst, wenn eine Zeile wegen eines Konflikts oder eines Fehlers nicht übernommen werden kann. Die Methoden, die diese Ereignisse behandeln, überprüfen die Art des Konflikts und legen fest, dass die Aktualisierungskonflikte von Client/Server gelöst werden sollen, indem die Änderung des Clients für die Serverdatenbank übernommen werden. Der Synchronisierungsbefehl, mit dem Aktualisierungen für die Serverdatenbank übernommen werden, enthält Logik, mit der festgelegt wird, in welchen Fällen eine Änderung erzwungen werden soll.Dieser Befehl ist im Code im nächsten Absatz dieses Themas "Entfernen von Servernachverfolgungsspalten aus Synchronisierungsbefehlen" enthalten.

Die zum Hinzufügen von Konfliktbehandlung auszuführenden Aktionen sind in C# und Visual Basic unterschiedlich.

So fügen Sie Konfliktbehandlung hinzu

  • Wenn Sie C# verwenden, fügen Sie NorthwindCache.cs und Form1.cs Code hinzu. Fügen Sie in NorthwindCache.cs nach dem Ende der NorthwindCacheSyncAgent-Klasse folgenden Code hinzu:

    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;
    
            }
    
        }
    }
    

    Ändern Sie in Form1.cs den Code im SynchronizeButton_Click-Ereignishandler, sodass die AddHandler-Methode aufgerufen wird, die Sie im vorherigen Schritt der Datei NorthwindCache.cs hinzugefügt haben:

    NorthwindCacheSyncAgent syncAgent = new NorthwindCacheSyncAgent();
    
    NorthwindCacheClientSyncProvider clientSyncProvider =
        (NorthwindCacheClientSyncProvider)syncAgent.LocalProvider;
    clientSyncProvider.AddHandlers();
    
    Microsoft.Synchronization.Data.SyncStatistics syncStats = 
        syncAgent.Synchronize();
    
  • Wenn Sie Visual Basic verwenden, fügen Sie in NorthwindCache.vb nach der End Class-Anweisung für die NorthwindCacheSyncAgent-Klasse folgenden Code hinzu.

    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
    

So synchronisieren Sie die Konfliktauflösung und zeigen diese an

  1. Drücken Sie die Taste F5.

  2. Aktualisieren Sie im Formular einen Datensatz, und klicken Sie dann auf die Schaltfläche Speichern.

  3. Aktualisieren Sie in Server-Explorer/Datenbank-Explorer den bereits im Formular geänderten Datensatz, ändern ihn jedoch in einen anderen Wert, und übernehmen Sie die Änderung.

  4. Wechseln Sie zum Formular zurück, und klicken dann auf Jetzt synchronisieren.

  5. Überprüfen Sie die Aktualisierung im Raster der Anwendung und in der Serverdatenbank. Beachten Sie, dass die auf dem Client vorgenommene Aktualisierung die Aktualisierung des Servers überschrieben hat.

Entfernen von Servernachverfolgungsspalten aus Synchronisierungsbefehlen

Wenn das Cache für lokale Datenbanken erstellt ist, werden die für die Änderungsnachverfolgung in der Serverdatenbank verwendeten Spalten auf den Client heruntergeladen. (In dieser exemplarischen Vorgehensweise sind dies die Spalten "CreationDate" und "LastEditDate".) Zur Unterstützung der bidirektionalen Synchronisierung und zum Gewährleisten der Datenkonvergenz bei Client und Server, entfernen Sie diese Spalten aus den SQL-Befehlen, die die Änderungen für die Serverdatenbank übernehmen. Sie können auch diejenigen Spalten aus den Befehlen entfernen, die die Änderungen vom Server auswählen, die für den Client übernommen werden sollen. Dies ist jedoch nicht erforderlich. Aufgrund von Beschränkungen einiger Schemaänderungen in der Clientdatenbank können die Spalten nicht verworfen werden. Weitere Informationen über Synchronisierungsbefehle finden Sie unter How to: Specify Snapshot, Download, Upload, and Bidirectional Synchronization.

Hinweis:

Wenn Sie die SQL Server 2008-Änderungsnachverfolgung verwenden, werden den Tabellen keine Nachverfolgungsspalten hinzugefügt. In diesem Fall müssen Sie die Befehle nicht ändern, die Änderungen für den Server übernehmen.

Mit dem folgenden Code werden zwei Befehle neu definiert, die als Eigenschaften des SyncAdapter-Objekts für die Tabelle "Customers" festgelegt sind: die InsertCommand()-Eigenschaft und die UpdateCommand()-Eigenschaft. Die mithilfe des Dialogfelds Datensynchronisierung konfigurieren erstellten Befehle enthalten Verweise auf die Spalten "CreationDate" und "LastEditDate". Im folgenden Code werden diese Befehle in der OnInitialized-Methode der CustomersSyncAdapter-Klasse neu definiert. Die DeleteCommand()-Eigenschaft wird nicht neu definiert, da sie keine Auswirkungen auf die Spalten "CreationDate" oder "LastEditDate" hat.

Die Variablen in den SQL-Befehlen werden verwendet, um Daten und Metadaten zwischen Synchronization Services, dem Client und dem Server zu übertragen. Die folgenden Sitzungsvariablen werden in den unten stehenden Befehlen verwendet:

  • @sync\_row\_count: Gibt die Anzahl der Zeilen zurück, die vom letzten Vorgang auf dem Server betroffen waren. In SQL Server-Datenbanken stellt @@rowcount den Wert für diese Variable bereit.

  • @sync\_force\_write: Wird verwendet, um das Übernehmen einer Änderung zu erzwingen, die wegen eines Konflikts oder eines Fehlers nicht übernommen wurde.

  • @sync\_last\_received\_anchor: Wird verwendet, um den Satz von Änderungen zu definieren, der während einer Sitzung synchronisiert werden soll.

Weitere Informationen über Sitzungsvariablen finden Sie unter How to: Use Session Variables.

So entfernen Sie Nachverfolgungsspalten aus Synchronisierungsbefehlen

  • Fügen Sie der NorthwindCache-Klasse (NorthwindCache.vb oder NorthwindCache.cs) nach der End Class-Anweisung für die NorthwindCacheServerSyncProvider-Klasse folgenden Code hinzu.

    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
    

Testen der Anwendung

So synchronisieren Sie eine Aktualisierung einer Nachverfolgungsspalte und zeigen diese an

  1. Drücken Sie die Taste F5.

  2. Aktualisieren Sie im Formular einen Datensatz, indem Sie einen Wert in der Spalte "LastEditDate" ändern, und klicken Sie dann auf die Schaltfläche Speichern.

  3. Wechseln Sie zum Formular zurück, und klicken Sie auf Jetzt synchronisieren.

  4. Überprüfen Sie die Aktualisierung im Raster der Anwendung und in der Serverdatenbank. Beachten Sie, dass der Spaltenwert des Servers die Aktualisierung des Clients überschrieben hat. Der Aktualisierungsprozess läuft wie folgt ab:

    1. Synchronization Services stellt fest, dass sich eine Zeile auf dem Client geändert hat.

    2. Während der Synchronisierung wird die Zeile hochgeladen und für die Tabelle in der Serverdatenbank übernommen. Die Nachverfolgungsspalten sind jedoch nicht in der Aktualisierungsanweisung enthalten. Tatsächlich führt Synchronization Services eine "Dummyaktualisierung" für die Tabelle durch.

    3. Daraufhin wird die Zeile an den Client zurückgegeben. Die Befehle, die Änderungen vom Server auswählen, enthalten jedoch die Nachverfolgungsspalten. Daher wird die auf dem Client vorgenommene Änderung mit dem Wert auf dem Server überschrieben.

Nächste Schritte

In dieser exemplarischen Vorgehensweise wurde die bidirektionale Synchronisierung mit grundlegender Konfliktbehandlung konfiguriert, und es wurden mögliche Probleme mit Servernachverfolgungsspalten in der Clientdatenbank behoben. Mit partiellen Klassen kann der Code für das Cache für lokale Datenbanken auch in anderer Hinsicht bedeutend erweitert werden. Beispielsweise können die SQL-Befehle neu definiert werden, die Änderungen von der Serverdatenbank auswählen, sodass Daten beim Herunterladen auf den Client gefiltert werden. Es wird empfohlen, die Gewusst-wie-Themen dieser Dokumentation zu lesen, um zu verstehen, wie Synchronisierungscode hinzugefügt oder geändert werden kann, damit die Anforderungen Ihrer Anwendung erfüllt werden. Weitere Informationen finden Sie unter How to Program Common Client and Server Synchronization Tasks.

Siehe auch

Konzepte

Übersicht über gelegentlich verbundene Anwendungen

Weitere Ressourcen

How to Program Common Client and Server Synchronization Tasks

Tools to Help You Develop Applications (Synchronization Services)

Änderungsprotokoll

Date

Versionsgeschichte

Grund

Juli 2008

Thema hinzugefügt.

SP1-Featureänderung.