在服务器和智能客户端的数据同步功能相信很多人会使用到,虽然Smart Client Software Factory已经内置了离线功能,但是对于数据同步的支持太单薄,好在微软已经为我们考虑到了,ADO.NET Sync Services的出现提供一种新的模式来改善原先的不足。
Sync Service提供4种同步的方式:仅下载同步、仅上传同步、双向同步、快照同步。
可以根据不同的场景需求来选择不同的同步方式。
在下面的Demo中,将详细叙述。
首先,从桌面的Client来了解下Sync Service,MS提供了很便捷的方式来快速实现。
创建一个WindosForm的Client程序。
在界面上添加一些控件,做一个简单的数据绑定效果。运行后程序如下
在工程中添加LocalDataCache文件。添加完后,会提示你同步操作。
选择好连接的源数据库,选择好新建的Client数据库。在高级中,选择创建的组件,你可以选择创建客户端和服务器端2端的组件。也可以只创建客户端或服务器端的。系统会根据你的选择来自动创建生成同步Provider,Agent等。选择完后,在左侧选择同步的数据库。
在客户端,一旦系统自动生成组件后,会自动创建一个sdf数据库,用户在本地保存数据,然后与服务器的数据库进行同步。
在左侧选中一个数据库后,则会出现一些规则。比如insert时比较哪个字段,update时比较哪个字段等。
配置完后,会在工程中生成一个.sync文件。
同步操作代码很简单,只需要2行即可。
一个简单的同步应用就完成了。很便捷吧。
下一个Demo,将演示如何实现使用WCF来实现同步。
这里将先创建一个WinFrom程序作为Client端,创建一个WCF Service作为服务器端。
同样在添加LocalDataCache文件时,必须选择客户端和服务器端的组件,这时,将服务器端选择WcfService工程即可。
此时,在Client工程中除了有.sync文件,还有.Client.sync文件,该文件配置了客户端的Provider等信息。服务器端则为.Server.sync文件。
同步方式一致。
下一个Demo,演示如何使用Web Site方式提供同步服务。微软这个组件,只能自动生成工程文件,但无法在WebSite中生成。只能通过手写一些代码来完成。其实效果一样,这样对于Sync Service的原理,应该更能理解。这里的Demo将演示Web Service。
在Web Site中,需要实现几个类。
当然啦,Service中的公开方法必不可少。另外还需要添加实现SyncAdapter的表的SyncAdapter。该adapter将对数据库表进行添、删、改的操作。并且可以自己实现这些Command语句、参数及当同步冲突时,采取你自定义的解决方法。
帖一段代码:当添加时,该如何实现。
还需要添加一个ServerSyncProvider继承DbServerSyncProvider。当同步时,会调用该Provider。通过Provider来操作Adapter。
当然,该Provider还提供一些事件,比如当冲突发生时,可以自定义解决方法。ApplyChangeFailed。在冲突发生后,可以取到两边的冲突数据。
在实现Web Service来同步数据时,需注意,在客户端添加Web引用时,需主要要修改生成的代理类中的一些地方。
注释掉系统自动生成的SyncGroupMetadata等类,改用调用Sync Service的dll中的。不然在同步时,会因为这些而出错。
当然啦,这些提供了同步时的扩展信息。目前,我还没有具体研究。
最后一个Demo,就是在Device中使用同步。
界面很简单。
最初启动后,数据库中没有记录,所以Load Data后,没有数据。
在同步数据后,数据就会保存到数据库中,再次Load Data后,本地数据库中就已存放数据了。
在Device中,使用本地数据库时,注意连接字符串的设置:应使用比如
总结:
Sync Services的出现,大大改善了在数据同步,使得我们可以更好的来关注致力于应用层面上。相信未来Sync Services还会有更好的改变。
在本文中,为什么使用Web Service而不是WCF的原因呢,在于Sync Services不能自动生成Web Site上的代码。
通过手写一些代码,能够了解Sync Services的很多实现细节。
参考:
张欣的WebCast--《移动数据访问新手段--ADO.NET Sync Services for device简介》
JustDI--《话说微软刚出的同步框架Sync Services》
代码下载:Sync_Solution.rar
项目DB下载:Sync_DB.rar
Author:AppleSeeker
Date:2008-07-18
在客户端PC或者智能设备本地存储数据的优势是明显的:
本地数据缓存,提供离线(offline)支持; 合理利用客户机的处理能力,提升系统响应速度; 减小服务器端应用服务器和数据服务器的压力; 适合偶尔连接的应用 OCA(Occasionally Connected Application )。
这种系统最令人头疼的问题就是“数据同步”问题。“数据同步”问题是必须解决的问题,也是必须开发的功能。然而,数据同步并不是用户需求。微软曾推出两种数据方案:远程数据访问(RDA), 合并复制(Merge replication),这两种方案主要用于以数据库作为数据源的数据同步,并且不是特别灵活,不能解决很多遗留系统问题。
ADO.NET Sync Services三个组成部分:运行时(runtime),元数据服务(Metadata Services),提供者(Provider)
ADO.NET Sync Services的好处在于:
1.提供Provider 模式,允许开发人员自定义提供者(Provider)以实现任意数据源之间的同步。
2.使得开发者关注同步运行时(Sync Runtime)
3.同步数据时不需要Replicating数据库
4.组件化,SOA架构,可以使用Web Service及WCF
ADO.NET Sync Services For Device就是为了在移动设备上同步数据提供了解决方案。
主要对比 | RDA | 合并复制 | Synchornization Services |
使用服务进行同步 | 否 | 否 | 是 |
支持异类数据库 | 否 | 否 | 是 |
跟踪增量更改 | 否 | 是 | 是 |
冲突检测与解决 | 否 | 是 | 是 |
在客户端轻松建立视图 | 否 | 否 | 是 |
自动初始化架构和数据 | 是 | 是 | 是 |
支持大型数据集 | 是 | 是 | 是 |
可在本地使用查询分析器 | 是 | 是 | 是 |
自动传播架构更改 | 否 | 是 | 否 |
在设备上使用 | 是 | 是 | 是 |
Sync Service提供4种同步的方式:仅下载同步、仅上传同步、双向同步、快照同步。
可以根据不同的场景需求来选择不同的同步方式。
在下面的Demo中,将详细叙述。
首先,从桌面的Client来了解下Sync Service,MS提供了很便捷的方式来快速实现。
创建一个WindosForm的Client程序。
在界面上添加一些控件,做一个简单的数据绑定效果。运行后程序如下
在工程中添加LocalDataCache文件。添加完后,会提示你同步操作。
选择好连接的源数据库,选择好新建的Client数据库。在高级中,选择创建的组件,你可以选择创建客户端和服务器端2端的组件。也可以只创建客户端或服务器端的。系统会根据你的选择来自动创建生成同步Provider,Agent等。选择完后,在左侧选择同步的数据库。
在客户端,一旦系统自动生成组件后,会自动创建一个sdf数据库,用户在本地保存数据,然后与服务器的数据库进行同步。
在左侧选中一个数据库后,则会出现一些规则。比如insert时比较哪个字段,update时比较哪个字段等。
配置完后,会在工程中生成一个.sync文件。
同步操作代码很简单,只需要2行即可。
1MyDBLocalDataCacheSyncAgent syncAgent = new MyDBLocalDataCacheSyncAgent();
2Microsoft.Synchronization.Data.SyncStatistics syncStats = syncAgent.Synchronize();
syncAgent--代理类。只需调用代理类的同步方法即可实现同步。当然啦,如果你想选择同步的方式的话。还需要添加代理类中,某个表的同步方式。2Microsoft.Synchronization.Data.SyncStatistics syncStats = syncAgent.Synchronize();
1syncAgent.Books.SyncDirection = Microsoft.Synchronization.Data.SyncDirection.Bidirectional;
这时,我指定的是双向同步。一个简单的同步应用就完成了。很便捷吧。
下一个Demo,将演示如何实现使用WCF来实现同步。
这里将先创建一个WinFrom程序作为Client端,创建一个WCF Service作为服务器端。
同样在添加LocalDataCache文件时,必须选择客户端和服务器端的组件,这时,将服务器端选择WcfService工程即可。
此时,在Client工程中除了有.sync文件,还有.Client.sync文件,该文件配置了客户端的Provider等信息。服务器端则为.Server.sync文件。
同步方式一致。
下一个Demo,演示如何使用Web Site方式提供同步服务。微软这个组件,只能自动生成工程文件,但无法在WebSite中生成。只能通过手写一些代码来完成。其实效果一样,这样对于Sync Service的原理,应该更能理解。这里的Demo将演示Web Service。
在Web Site中,需要实现几个类。
当然啦,Service中的公开方法必不可少。另外还需要添加实现SyncAdapter的表的SyncAdapter。该adapter将对数据库表进行添、删、改的操作。并且可以自己实现这些Command语句、参数及当同步冲突时,采取你自定义的解决方法。
帖一段代码:当添加时,该如何实现。
1 // BooksSyncTableInsertCommand command.
2 this.InsertCommand = new System.Data.SqlClient.SqlCommand();
3 this.InsertCommand.CommandText = @" SET IDENTITY_INSERT dbo.Books ON INSERT INTO dbo.Books ([SysNo], [BookName], [CSBN], [AuthorSysNo], [PublishTime], [LastEditDate], [CreationDate]) VALUES (@SysNo, @BookName, @CSBN, @AuthorSysNo, @PublishTime, @LastEditDate, @CreationDate) SET @sync_row_count = @@rowcount SET IDENTITY_INSERT dbo.Books OFF ";
4 this.InsertCommand.CommandType = System.Data.CommandType.Text;
5 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@SysNo", System.Data.SqlDbType.Int));
6 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@BookName", System.Data.SqlDbType.NVarChar));
7 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CSBN", System.Data.SqlDbType.NVarChar));
8 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@AuthorSysNo", System.Data.SqlDbType.Int));
9 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@PublishTime", System.Data.SqlDbType.DateTime));
10 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@LastEditDate", System.Data.SqlDbType.DateTime));
11 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CreationDate", System.Data.SqlDbType.DateTime));
12 System.Data.SqlClient.SqlParameter insertcommand_sync_row_countParameter = new System.Data.SqlClient.SqlParameter("@sync_row_count", System.Data.SqlDbType.Int);
13 insertcommand_sync_row_countParameter.Direction = System.Data.ParameterDirection.Output;
14 this.InsertCommand.Parameters.Add(insertcommand_sync_row_countParameter);
2 this.InsertCommand = new System.Data.SqlClient.SqlCommand();
3 this.InsertCommand.CommandText = @" SET IDENTITY_INSERT dbo.Books ON INSERT INTO dbo.Books ([SysNo], [BookName], [CSBN], [AuthorSysNo], [PublishTime], [LastEditDate], [CreationDate]) VALUES (@SysNo, @BookName, @CSBN, @AuthorSysNo, @PublishTime, @LastEditDate, @CreationDate) SET @sync_row_count = @@rowcount SET IDENTITY_INSERT dbo.Books OFF ";
4 this.InsertCommand.CommandType = System.Data.CommandType.Text;
5 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@SysNo", System.Data.SqlDbType.Int));
6 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@BookName", System.Data.SqlDbType.NVarChar));
7 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CSBN", System.Data.SqlDbType.NVarChar));
8 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@AuthorSysNo", System.Data.SqlDbType.Int));
9 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@PublishTime", System.Data.SqlDbType.DateTime));
10 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@LastEditDate", System.Data.SqlDbType.DateTime));
11 this.InsertCommand.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CreationDate", System.Data.SqlDbType.DateTime));
12 System.Data.SqlClient.SqlParameter insertcommand_sync_row_countParameter = new System.Data.SqlClient.SqlParameter("@sync_row_count", System.Data.SqlDbType.Int);
13 insertcommand_sync_row_countParameter.Direction = System.Data.ParameterDirection.Output;
14 this.InsertCommand.Parameters.Add(insertcommand_sync_row_countParameter);
还需要添加一个ServerSyncProvider继承DbServerSyncProvider。当同步时,会调用该Provider。通过Provider来操作Adapter。
当然,该Provider还提供一些事件,比如当冲突发生时,可以自定义解决方法。ApplyChangeFailed。在冲突发生后,可以取到两边的冲突数据。
1 private void OnInitialized()
2 {
3 this.ApplyChangeFailed += new EventHandler<Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs>(MyDBLocalDataCacheServerSyncProvider_ApplyChangeFailed);
4 }
5
6 void MyDBLocalDataCacheServerSyncProvider_ApplyChangeFailed(object sender, Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e)
7 {
8 System.Data.DataTable dtS = e.Conflict.ServerChange;
9 System.Data.DataTable dtC = e.Conflict.ClientChange;
10
11 System.Console.WriteLine("ss");
12 }
2 {
3 this.ApplyChangeFailed += new EventHandler<Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs>(MyDBLocalDataCacheServerSyncProvider_ApplyChangeFailed);
4 }
5
6 void MyDBLocalDataCacheServerSyncProvider_ApplyChangeFailed(object sender, Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e)
7 {
8 System.Data.DataTable dtS = e.Conflict.ServerChange;
9 System.Data.DataTable dtC = e.Conflict.ClientChange;
10
11 System.Console.WriteLine("ss");
12 }
在实现Web Service来同步数据时,需注意,在客户端添加Web引用时,需主要要修改生成的代理类中的一些地方。
注释掉系统自动生成的SyncGroupMetadata等类,改用调用Sync Service的dll中的。不然在同步时,会因为这些而出错。
当然啦,这些提供了同步时的扩展信息。目前,我还没有具体研究。
最后一个Demo,就是在Device中使用同步。
界面很简单。
最初启动后,数据库中没有记录,所以Load Data后,没有数据。
在同步数据后,数据就会保存到数据库中,再次Load Data后,本地数据库中就已存放数据了。
在Device中,使用本地数据库时,注意连接字符串的设置:应使用比如
1this.ConnectionString = @"Data Source= \Program Files\DeviceClient\MyDB.sdf";
不支持|DataDirectory|这种方式。总结:
Sync Services的出现,大大改善了在数据同步,使得我们可以更好的来关注致力于应用层面上。相信未来Sync Services还会有更好的改变。
在本文中,为什么使用Web Service而不是WCF的原因呢,在于Sync Services不能自动生成Web Site上的代码。
通过手写一些代码,能够了解Sync Services的很多实现细节。
参考:
张欣的WebCast--《移动数据访问新手段--ADO.NET Sync Services for device简介》
JustDI--《话说微软刚出的同步框架Sync Services》
代码下载:Sync_Solution.rar
项目DB下载:Sync_DB.rar
Author:AppleSeeker
Date:2008-07-18