Freigeben über


Vorgehensweise: Konfigurieren der n-Ebenen-Synchronisierung

In diesem Thema wird gezeigt, wie Sie die n-Ebenen-Synchronisierung für Sync Framework konfigurieren können. Die Beispiele in diesem Thema beziehen sich auf die folgenden Sync Framework-Typen:

Informationen dazu, wie Sie Beispielcode ausführen können, finden Sie unter "Beispielanwendungen in den Themen zur Vorgehensweise" in Programmieren von allgemeinen Client- und Serversynchronisierungsaufgaben.

n-Ebenen-Synchronisierung

Bei einer n-Ebenen-Synchronisierungsarchitektur sind die Synchronisierungskomponenten, wie in der folgenden Abbildung dargestellt, über mehrere Ebenen verteilt.

N-Ebenen-Synchronisierungstopologie

In einer 2-Ebenen-Architektur befinden sich alle Komponenten auf dem Client, und der Client kommuniziert direkt mit dem Server. In einer n-Ebenen-Architektur befindet sich der Serversynchronisierungsanbieter auf dem Server oder einer anderen Ebene, und die Kommunikation zwischen den Ebenen erfolgt über das ServerSyncProviderProxy-Objekt und einen Dienst, wie z. B. den Windows Communication Foundation (WCF)-Dienst. Eine der Stärken von Sync Framework besteht in der Einfachheit, mit der Sie Code von einer 2-Ebenen-Architektur in eine n-Ebenen-Architektur verschieben können. Wenn der Code ordnungsgemäß zugeordnet ist, bedarf es nach dem Erstellen eines Diensts und dem Hinzufügen eines Proxys nur einer kleinen Änderung des Synchronisierungs-Agent-Codes. Der Client- und der Serversynchronisierungsanbieter müssen nicht geändert werden.

Beispiel

Die folgenden Codebeispiele zeigen die Hauptkomponenten, die an einer n-Ebenen- Architektur beteiligt sind. Es sind zusätzliche WCF-Komponenten erforderlich. Diese Komponenten werden für Sie generiert, wenn Sie Visual Studio 2008 verwenden. Weitere Informationen finden Sie in der Visual Studio-Dokumentation.

Schlüsselbestandteile der API

Sie finden in diesem Abschnitt Codebeispiele, aus denen die Gemeinsamkeiten von 2-Ebenen- und n-Ebenen-Architekturen hervorgehen und die diejenigen Schlüsselbestandteile der API zeigen, die zum Konfigurieren der n-Ebenen-Synchronisierung verwendet werden. Das folgende Codebeispiel stammt aus einer Klasse, die von der SyncAgent-Klasse abgeleitet ist. Bei einer 2-Ebenen-Synchronisierung wird auf den Clientanbieter und den Serveranbieter direkt im Synchronisierungs-Agent als lokaler und als Remote-Anbieter verwiesen.

this.LocalProvider = new SampleClientSyncProvider();

this.RemoteProvider = new SampleServerSyncProvider();
Me.LocalProvider = New SampleClientSyncProvider()

Me.RemoteProvider = New SampleServerSyncProvider()

Das folgende Codebeispiel verweist wie im 2-Ebenen-Beispiel direkt auf den Clientanbieter. Der Remote-Anbieter verweist jetzt aber auf einen Proxy und nicht direkt auf den Serveranbieter. Der Proxy wird erstellt, indem ein Verweis an einen WCF-Dienst übergeben wird.

this.LocalProvider = new SampleClientSyncProvider();

ServiceReference.ServiceForSyncClient serviceProxy = new ServiceReference.ServiceForSyncClient();
this.RemoteProvider = new ServerSyncProviderProxy(serviceProxy);
Me.LocalProvider = New SampleClientSyncProvider()

Dim serviceProxy As New ServiceReference.ServiceForSyncClient()
Me.RemoteProvider = New ServerSyncProviderProxy(serviceProxy)

Die folgenden Codebeispiele erstellen Client- und Serveranbieter. Dieser Code ist in 2-Ebenen- und n-Ebenen-Architekturen identisch.

public class SampleClientSyncProvider : SqlCeClientSyncProvider
{

    public SampleClientSyncProvider()
    {
        //Specify a connection string for the sample client database.
        Utility util = new Utility();
        this.ConnectionString = util.ClientConnString;
    }
}
public class SampleServerSyncProvider : DbServerSyncProvider
{
    public SampleServerSyncProvider()
    {
        //Create a connection to the sample server database.
        Utility util = new Utility();
        SqlConnection serverConn = new SqlConnection(util.ServerConnString);
        this.Connection = serverConn;

        //Create a command to retrieve a new anchor value from
        //the server.
        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 manually, or
        //by using the SqlSyncAdapterBuilder as in the following
        //code.
        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();
        customerSyncAdapter.TableName = "Customer";
        this.SyncAdapters.Add(customerSyncAdapter);
    }
}
Public Class SampleClientSyncProvider
    Inherits SqlCeClientSyncProvider

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

    End Sub
End Class
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(util.ServerConnString)
        Me.Connection = serverConn

        'Create a command to retrieve a new anchor value from
        'the server.
        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 manually, or
        'by using the SqlSyncAdapterBuilder as in the following
        'code.
        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
End Class

Das folgende Codebeispiel erstellt eine Schnittstelle, die der Dienst implementiert. Die Schnittstelle enthält die vier Schlüsselmethoden des Serveranbieters.

[ServiceContract]
public interface IServiceForSync
{
    [OperationContract()]
    SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession);

    [OperationContract()]
    SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession);

    [OperationContract()]
    SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession);

    [OperationContract()]
    SyncServerInfo GetServerInfo(SyncSession syncSession);
}
<ServiceContract()> _
Public Interface IServiceForSync
    <OperationContract()> _
    Function ApplyChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal dataSet As DataSet, ByVal syncSession As SyncSession) As SyncContext

    <OperationContract()> _
    Function GetChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal syncSession As SyncSession) As SyncContext

    <OperationContract()> _
    Function GetSchema(ByVal tableNames As Collection(Of String), ByVal syncSession As SyncSession) As SyncSchema

    <OperationContract()> _
    Function GetServerInfo(ByVal syncSession As SyncSession) As SyncServerInfo
End Interface

Das folgende Codebeispiel erstellt einen Dienst. Dieser Dienst implementiert die Schnittstelle, die im vorherigen Codebeispiel erstellt wurde, und verweist auf den Serveranbieter.

public class ServiceForSync : IServiceForSync
{

    private SampleServerSyncProvider _serverSyncProvider;

    public ServiceForSync()
    {
         this._serverSyncProvider = new SampleServerSyncProvider();
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession) {
        return this._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession) {
        return this._serverSyncProvider.GetChanges(groupMetadata, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession) {
        return this._serverSyncProvider.GetSchema(tableNames, syncSession);
    }
    
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public virtual SyncServerInfo GetServerInfo(SyncSession syncSession) {
        return this._serverSyncProvider.GetServerInfo(syncSession);
    }       
}
Public Class ServiceForSync
    Implements IServiceForSync

    Private _serverSyncProvider As SampleServerSyncProvider


    Public Sub New()
        Me._serverSyncProvider = New SampleServerSyncProvider()
    End Sub


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function ApplyChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal dataSet As DataSet, ByVal syncSession As SyncSession) As SyncContext
        Return Me._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession)
    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetChanges(ByVal groupMetadata As SyncGroupMetadata, ByVal syncSession As SyncSession) As SyncContext
        Return Me._serverSyncProvider.GetChanges(groupMetadata, syncSession)

    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetSchema(ByVal tableNames As Collection(Of String), ByVal syncSession As SyncSession) As SyncSchema
        Return Me._serverSyncProvider.GetSchema(tableNames, syncSession)
    End Function


    <System.Diagnostics.DebuggerNonUserCodeAttribute()> _
    Public Overridable Function GetServerInfo(ByVal syncSession As SyncSession) As SyncServerInfo
        Return Me._serverSyncProvider.GetServerInfo(syncSession)
    End Function
End Class

Siehe auch

Konzepte

Programmieren von allgemeinen Client- und Serversynchronisierungsaufgaben