[原创]用代码学 Synchronization Services for ADO.NET(1) - 创建一个简单的数据同步小程序
写在前面:
Synchronization Services for ADO.NET 是微软推出的同步框架( Microsoft Synchronization Framework)中的一员,也是其重要的组成部分。使用它,我们实现基于数据库的数据智能同步,即:从客户端 的SSCE(SQL 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了,具体情况后面介绍。
后两者,你可以从以下地址免费下载:
写到这里,感觉总是用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 SERVER、Oracle在内的多种数据库,微软对服务器端的数据库的类型并没有限制,理论上你可以选择任何品牌的数据库作为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 Table,Sync Table的一个主要属性是SyncDirection,它决定了数据同步的方向,其可选择的类型如下:
· Bidirectional 首次同步期间,客户端通常从服务器下载架构和一个初始数据集。执行后续同步时,客户端将更改上载到服务器,然后从服务器下载更改。
· DownloadOnly 首次同步期间,客户端通常从服务器下载架构和一个初始数据集。执行后续同步时,客户端从服务器下载更改。
· Snapshot 客户端将从服务器下载一个数据集。每次同步期间,这些数据都将完全刷新。
· UploadOnly 首次同步期间,客户端通常从服务器下载架构。执行后续同步时,客户端将更改上载到服务器。
通过设置不同表的SyncDirection,我们可以灵活的决定哪些表只进行下载或只进行上传操作。比如说,对于小数据量的、并且不需要更新的基础表,我们可以使用SnapShot方式-每次全部下载更新一边,而对于订单这种不断更新的表,我们使用Bidirectonal-不断的双向更新。
Sync Group:Sync Group的概念比较简单,多个Sync Table可以定义到一个SyncGroup中。在提交数据中,同一Sync Group将由一个事务进行提交。为了保证数据的完整性,主从表结构的表应该定义到同一Sync Group中。
总之,想先简单的介绍一下概念,结果还是说了以上这么多,看来SyncDB也不是一个简单的构架-可以简简单单的说清楚。好吧,下面可以进入CODE阶段了。
编写CODE
我们将采用一个SyncDB的最简模型来做一个演示,使用Snapshot作为同步方式,即:从Server Database下载一个数据集到Client Database中,下载前完全删除客户端原有的数据。
1.创建 DB Provider
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
//Create Server/Client Provider and SyncAgent.
DbServerSyncProvider serverProvider = new DbServerSyncProvider();
serverProvider.Connection = this.serverConn;
SqlCeClientSyncProvider clientProvider = new SqlCeClientSyncProvider(clientConnString);
2.创建 Sync Agent,并设置同步两端的Provider
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
SyncAgent syncAgent = new SyncAgent();
syncAgent.RemoteProvider = serverProvider;
syncAgent.LocalProvider = clientProvider;
3.创建SyncTable,并设置同步方向为Snapshot,若Client DB 中已经存在此表,则删除后在重新创建。最后将SyncTable添加到SyncAgent中。
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
// 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中。
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
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 DB(SQL SERVER)同步到了Client DB(SSCE)中。
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
// Do Sync
SyncStatistics syncStatistics = syncAgent.Synchronize();
怎么样,看上去是不是很简单?为了方便大家的调试,我将代码源码共享在下面:
SyncDBSample Cases - 1.rar(已经失效)
以上就一个最简单的同步程序,更多的功能和技巧,请期待下一章。
宝贵的意见,也希望大家多多提出,谢谢。