如何使用sql将服务器同步到客户端数据库

时间:2014-03-31 07:21:11

标签: c# sql database synchronization

我正在开发项目,我需要为脱机应用程序使用数据库同步。 在某种程度上我成功了,我完成了使用下面代码

的客户端到服务器的同步
 DbServerSyncProvider serverSyncProvider = new DbServerSyncProvider();

            SyncAgent syncAgent = new SyncAgent();               
            syncAgent.RemoteProvider = serverSyncProvider;


            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();

            //
            // 2. Prepare server db connection and attach it to the sync agent
            //
            builder["Data Source"] = textServerMachine.Text;
            builder["integrated Security"] = true;
            builder["Initial Catalog"] = "pub";
            SqlConnection serverConnection = new SqlConnection(builder.ConnectionString);

            serverSyncProvider.Connection = serverConnection;


            //
            // 3. Prepare client db connection and attach it to the sync provider
            //                                
            string connString = "Data Source=" + dbPathTextBox.Text;

            if (false == File.Exists(dbPathTextBox.Text))
            {                 
                SqlCeEngine clientEngine = new SqlCeEngine(connString);
                clientEngine.CreateDatabase();
                clientEngine.Dispose();
            }                
            SqlCeClientSyncProvider clientSyncProvider = new SqlCeClientSyncProvider(connString);
            syncAgent.LocalProvider = clientSyncProvider;


            //
            // 4. Create SyncTables and SyncGroups
            // To sync a table, a SyncTable object needs to be created and setup with desired properties:
            // TableCreationOption tells the agent how to initialize the new table in the local database
            // SyncDirection is how changes from with respect to client {Download, Upload, Bidirectional or Snapshot}
            //
            //
            SyncTable tableOrders = new SyncTable("orders");
            tableOrders.CreationOption = TableCreationOption.DropExistingOrCreateNewTable;
            tableOrders.SyncDirection = SyncDirection.Bidirectional;

            SyncTable tableOrderDetails = new SyncTable("order_details");
            tableOrderDetails.CreationOption = TableCreationOption.DropExistingOrCreateNewTable;
            tableOrderDetails.SyncDirection = SyncDirection.Bidirectional;

            //
            // Sync changes for both tables as one bunch, using SyncGroup object
            // This is important if the tables has PK-FK relationship, grouping will ensure that 
            // and FK change won't be applied before its PK is applied
            //
            //
            SyncGroup orderGroup = new SyncGroup("AllChanges");
            tableOrders.SyncGroup = orderGroup;
            tableOrderDetails.SyncGroup = orderGroup;

            syncAgent.Configuration.SyncTables.Add(tableOrders);
            syncAgent.Configuration.SyncTables.Add(tableOrderDetails);



            //
            // 5. Create sync adapter for each sync table and attach it to the server provider
            // Following DataAdapter style in ADO.NET, SyncAdapte is the equivelent for
            // Sync. SyncAdapterBuilder is a helper class to simplify the process of 
            // creating sync commands.                 
            //
            //

            SqlSyncAdapterBuilder ordersBuilder = new SqlSyncAdapterBuilder();                
            ordersBuilder.Connection = serverConnection;
            ordersBuilder.SyncDirection = SyncDirection.Bidirectional;

            // base table
            ordersBuilder.TableName = "orders";
            ordersBuilder.DataColumns.Add("order_id");
            ordersBuilder.DataColumns.Add("order_date");

            // tombstone table
            ordersBuilder.TombstoneTableName = "orders_tombstone";
            ordersBuilder.TombstoneDataColumns.Add("order_id");
            ordersBuilder.TombstoneDataColumns.Add("order_date");

            // tracking\sync columns
            ordersBuilder.CreationTrackingColumn = @"create_timestamp";
            ordersBuilder.UpdateTrackingColumn = @"update_timestamp";
            ordersBuilder.DeletionTrackingColumn = @"update_timestamp";
            ordersBuilder.UpdateOriginatorIdColumn = @"update_originator_id";

            SyncAdapter ordersSyncAdapter = ordersBuilder.ToSyncAdapter();
            ((SqlParameter)ordersSyncAdapter.SelectIncrementalInsertsCommand.Parameters["@sync_last_received_anchor"]).DbType = DbType.Binary;
            ((SqlParameter)ordersSyncAdapter.SelectIncrementalInsertsCommand.Parameters["@sync_new_received_anchor"]).DbType = DbType.Binary;
            serverSyncProvider.SyncAdapters.Add(ordersSyncAdapter);


            SqlSyncAdapterBuilder orderDetailsBuilder = new SqlSyncAdapterBuilder();
            orderDetailsBuilder.SyncDirection = SyncDirection.Bidirectional;
            orderDetailsBuilder.Connection = serverConnection;

            // base table
            orderDetailsBuilder.TableName = "order_details";
            orderDetailsBuilder.DataColumns.Add("order_id");
            orderDetailsBuilder.DataColumns.Add("order_details_id");
            orderDetailsBuilder.DataColumns.Add("product");
            orderDetailsBuilder.DataColumns.Add("quantity");

            // tombstone table
            orderDetailsBuilder.TombstoneTableName = "order_details_tombstone";
            orderDetailsBuilder.TombstoneDataColumns.Add("order_id");
            orderDetailsBuilder.TombstoneDataColumns.Add("order_details_id");
            orderDetailsBuilder.TombstoneDataColumns.Add("product");
            orderDetailsBuilder.TombstoneDataColumns.Add("quantity");

            // tracking\sync columns
            orderDetailsBuilder.CreationTrackingColumn = @"create_timestamp";
            orderDetailsBuilder.UpdateTrackingColumn = @"update_timestamp";
            orderDetailsBuilder.DeletionTrackingColumn = @"update_timestamp";
            orderDetailsBuilder.UpdateOriginatorIdColumn = @"update_originator_id";


            SyncAdapter orderDetailsSyncAdapter = orderDetailsBuilder.ToSyncAdapter();
            ((SqlParameter)orderDetailsSyncAdapter.SelectIncrementalInsertsCommand.Parameters["@sync_last_received_anchor"]).DbType = DbType.Binary;
            ((SqlParameter)orderDetailsSyncAdapter.SelectIncrementalInsertsCommand.Parameters["@sync_new_received_anchor"]).DbType = DbType.Binary;
            serverSyncProvider.SyncAdapters.Add(orderDetailsSyncAdapter);


            //
            // 6. Setup provider wide commands
            // There are two commands on the provider itself and not on a table sync adapter:
            // SelectNewAnchorCommand: Returns the new high watermark for current sync, this value is
            // stored at the client and used the low watermark in the next sync
            // SelectClientIdCommand: Finds out the client ID on the server, this command helps
            // avoid downloading changes that the client had made before and applied to the server
            //
            //

            // select new anchor command
            SqlCommand anchorCmd = new SqlCommand();
            anchorCmd.CommandType = CommandType.Text;
            anchorCmd.CommandText = "Select @" + SyncSession.SyncNewReceivedAnchor + " = @@DBTS";  // for SQL Server 2005 SP2, use "min_active_rowversion() - 1"
            anchorCmd.Parameters.Add("@" + SyncSession.SyncNewReceivedAnchor, SqlDbType.Timestamp).Direction = ParameterDirection.Output;

            serverSyncProvider.SelectNewAnchorCommand = anchorCmd;

            // client ID command (give the client id of 1)
            // in remote server scenario (middle tear), this command will reference a local client table for the ID               
            SqlCommand clientIdCmd = new SqlCommand();
            clientIdCmd.CommandType = CommandType.Text;
            clientIdCmd.CommandText = "SELECT @" + SyncSession.SyncOriginatorId + " = 1";
            clientIdCmd.Parameters.Add("@" + SyncSession.SyncOriginatorId, SqlDbType.Int).Direction = ParameterDirection.Output;

            serverSyncProvider.SelectClientIdCommand = clientIdCmd;

现在的问题是如何从服务器同步到客户端。我认为改变clientSyncProvider会有所帮助,但没有像selectServerIdCommand那样的东西。所以不知道该怎么做。我尝试了很多搜索,但不能很好地适应。

0 个答案:

没有答案