[原创]用代码学 Synchronization Services for ADO.NET(1) - 创建一个简单的数据同步小程序

写在前面:

Synchronization Services for ADO.NET 是微软推出的同步框架( Microsoft Synchronization Framework)中的一员,也是其重要的组成部分。使用它,我们实现基于数据库的数据智能同步,即:从客户端 SSCESQL Server Compact Edition)数据库 至服务器端 数据库(SQL  SERVER或其他数据库,如Oracle等) ,我们可以进行单向、或者双向的数据智能同步。

从产品的构架灵活度,提供的各种特性、以及稳定性能等来说,想要将Synchronization Services for ADO.NET理解透彻,我们还需要了解的更多。不过别着急,下面的几个章节我会详细的和大家介绍。如同标题,让我们从代码开始,让你用最短的时间就会用Synchronization Services for ADO.NET

 

准备工作:

你需要安装如下产品才能正常使用Synchronization Services for ADO.NET

·         SQL Server ,推荐SQL Server 2008,从SQL SERVER 2000提供支持

·         Visual Studio, 推荐2008,从2005提供支持

·         Sql Server Compact Edition,仅支持SSCE35-RTM,推荐SP1

·         Synchronization Services for ADO.NET  1.0,目前已经出2.0了,具体情况后面介绍。

后两者,你可以从以下地址免费下载:

Microsoft SQL Server Compact 3.5 Service Pack 1 and Synchronization Services for ADO.NET version 1.0 Service Pack 1 for Windows Desktop

 

写到这里,感觉总是用Synchronization Services for ADO.NET来称呼产品,既费事有累赘。还是让我们用微软的开发代码(code name)来称呼吧,以后所有文章Synchronization Services for ADO.NET均称为SyncDB

 

创建服务器端数据库

手动创建数据库,名称为:SyncSamplesDb,然后执行下面的 Script

USE [SyncSamplesDb]

GO

/****** Object:  Table [dbo].[Customers]    ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE TABLE [dbo].[Customers](

      [CustomerID] [nchar](5) NOT NULL,

      [CompanyName] [nvarchar](40) NOT NULL,

      [ContactName] [nvarchar](30) NULL,

 CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED

(

      [CustomerID] ASC

)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Customers] DISABLE CHANGE_TRACKING

GO

INSERT [dbo].[Customers] ([CustomerID], [CompanyName], [ContactName]) VALUES (N'ALFKI', N'Alfreds Futterkiste', N'Maria Anders')

INSERT [dbo].[Customers] ([CustomerID], [CompanyName], [ContactName]) VALUES (N'ANATR', N'Ana Trujillo Emparedados y helados', N'Ana Trujillo')

INSERT [dbo].[Customers] ([CustomerID], [CompanyName], [ContactName]) VALUES (N'ANTON', N'Antonio Moreno Taquer', N'Antonio Moreno')

 

我们创建了一个非常简单的Customer表,共三个字段,一个主键。同时我们插入3条记录,一个简单的customers表便生成了。我们就从这个简单的表开始我们的代码历程。

 

创建项目

打开Visual Studio 2008,创建一个 C# Console程序,对于NET Framework 的版本-  2.0 3.5 SyncDB均提供支持。您还需要向项目添加以下SyncDB的引用:

·         Microsoft.Synchronization.Data

·         Microsoft.Synchronization.Data.Server

·         Microsoft.Synchronization.Data.SqlServerCe

·         System.Data.SqlServerCe

上面的DLL的具体作用,我稍后会详细介绍,让我们继续完成CODE

 

撰写程序代码

简单了解构架

在写代码之前,让我们先看一下SyncDB的体系构架图,下面是双层(2-Tire)架构的机构。

 

从上述结构我们可以看到,SyncDB构架的两端均为数据库,数据库中存储了我们将要同步或已经同步完成后的数据。中间的各个部分组件 - 组成了SyncDB构架,它们分别是:

DB Provider : SyncDB构架中共有两个Provider,分别是 Client Provider Server Provider。这里使用Provider的主要目的是为了对数据库进行解耦,避免了Sync Agent与数据库捆绑的过紧,同时也将SyncAgent与数据库的具体操作隔离开。同样,对于数据库的数据的检索、更新操作、冲突检测等功能,也在这里进行。

 Client Provider :与 Client Database匹配使用,目前SyncDB的客户端数据库支持SSCE,并未提供其他数据库的接口。这也就意味着目前SyncDB的 客户端数据只能使用SSCE。不过目前SSCE的表现还是不错的,紧凑小巧高效,并且提供跨平台的支持,而且还免费。与此同时,微软正在不断投入资源,将SSCE打造成桌面小型数据库的替代品。相信未来SSCE会提供更高效的性能和更多的功能。

Server Provider:与 Server Database匹配使用,目前Server Database支持包括SQL SERVEROracle在内的多种数据库,微软对服务器端的数据库的类型并没有限制,理论上你可以选择任何品牌的数据库作为Server Database

Sync Adapter:位于Server Provider内,针对Server Provider主要提供3点功能:获得Schema、检索数据更新、以及更新数据。SyncDB的Sync Adapter模仿了ADO.NET Data Adapter,为每一个表都提供了一个Sync Adapter,并定义了各种数据检索交换所使用的DBCommand,提供了充分的灵活性。

Sync Agent:位于整个构架的中心位置,主要功能为:1.循环遍历需要同步的表,调用Client Provider检索并更新Client Database,调用Server Provider检索并更新Server Database。你把他想象成中央调度的总部就行,所有的同步指令都是从这里发出的。

Sync Tables: 针对于每一个要同步的表,我们都需要定义一个Sync TableSync Table的一个主要属性是SyncDirection,它决定了数据同步的方向,其可选择的类型如下:

·         Bidirectional 首次同步期间,客户端通常从服务器下载架构和一个初始数据集。执行后续同步时,客户端将更改上载到服务器,然后从服务器下载更改。

·         DownloadOnly 首次同步期间,客户端通常从服务器下载架构和一个初始数据集。执行后续同步时,客户端从服务器下载更改。

·         Snapshot 客户端将从服务器下载一个数据集。每次同步期间,这些数据都将完全刷新。

·         UploadOnly 首次同步期间,客户端通常从服务器下载架构。执行后续同步时,客户端将更改上载到服务器。

通过设置不同表的SyncDirection,我们可以灵活的决定哪些表只进行下载或只进行上传操作。比如说,对于小数据量的、并且不需要更新的基础表,我们可以使用SnapShot方式-每次全部下载更新一边,而对于订单这种不断更新的表,我们使用Bidirectonal-不断的双向更新。

Sync GroupSync Group的概念比较简单,多个Sync Table可以定义到一个SyncGroup中。在提交数据中,同一Sync Group将由一个事务进行提交。为了保证数据的完整性,主从表结构的表应该定义到同一Sync Group中。

 

总之,想先简单的介绍一下概念,结果还是说了以上这么多,看来SyncDB也不是一个简单的构架-可以简简单单的说清楚。好吧,下面可以进入CODE阶段了。

 

编写CODE

 

我们将采用一个SyncDB的最简模型来做一个演示,使用Snapshot作为同步方式,即:从Server Database下载一个数据集到Client Database中,下载前完全删除客户端原有的数据。

 

1.创建 DB Provider

 

 

Code
       //Create Server/Client Provider and SyncAgent.

DbServerSyncProvider serverProvider
= new DbServerSyncProvider();
serverProvider.Connection
= this.serverConn;
SqlCeClientSyncProvider clientProvider
= new SqlCeClientSyncProvider(clientConnString);

 

 

 

2.创建 Sync Agent,并设置同步两端的Provider

 

 

Code
SyncAgent syncAgent = new SyncAgent();
syncAgent.RemoteProvider
= serverProvider;
syncAgent.LocalProvider
= clientProvider;

 

 

 

3.创建SyncTable,并设置同步方向为Snapshot,若Client DB 中已经存在此表,则删除后在重新创建。最后将SyncTable添加到SyncAgent中。  

 

Code
// create SyncTable objects for tables which needs to be synchronized.
SyncTable syncTable = new SyncTable("customers");
syncTable.CreationOption
= TableCreationOption.DropExistingOrCreateNewTable;
syncTable.SyncDirection
= SyncDirection.Snapshot;
syncAgent.Configuration.SyncTables.Add(syncTable);

 

 

 

 

 

4.创建SyncAdapter。针对每一个需要同步的表,创建一个SyncAdapter。由于我们的目的是Snapshot一个表,所以这里我们只创建一个SyncAdapter即可。同样的,SyncAdapter提供多种DBCommand可供使用,对于Snapshot只需要用到SelectIncInsertCmd。最后我们把SyncAdapter添加到ServerProvider中。

 

 

Code
SyncAdapter syncAdapter = new SyncAdapter("customers");

System.Data.SqlClient.SqlCommand selectIncInsertCmd
= this.serverConn.CreateCommand();
selectIncInsertCmd.CommandText
= "select CustomerID,CompanyName,ContactName from customers";
syncAdapter.SelectIncrementalInsertsCommand
= selectIncInsertCmd;
serverProvider.SyncAdapters.Add(syncAdapter);

 

 

5.最有一步:同步。执行完毕后,你就可以观察到 Customers表已经成功的从Server DBSQL SERVER)同步到了Client DBSSCE)中。

 

Code
// Do Sync
SyncStatistics syncStatistics = syncAgent.Synchronize();

 

 

 

 

怎么样,看上去是不是很简单?为了方便大家的调试,我将代码源码共享在下面:

 

 SyncDBSample Cases - 1.rar(已经失效)

 

以上就一个最简单的同步程序,更多的功能和技巧,请期待下一章。

宝贵的意见,也希望大家多多提出,谢谢。

 

 

posted on 2008-09-02 01:33  梁一鸣  阅读(4086)  评论(20编辑  收藏  举报