前言:
Sync Framework 是一个功能完善的同步平台,实现了应用程序、服务和设备的协作和脱机访问。Sync Framework 提供了一些可支持在脱机状态下漫游、共享数据和获取数据的技术和工具。通过使用 Sync Framework,开发人员可以构建同步生态系统,通过在任意网络上使用任意协议,将任意应用程序与任意存储区中的数据集成在一起。
---摘自《微软.Sync Framework帮助文档》
接触SQLSERVER已经有六年多了。对于SQLSERVER中提供的各种功能,多少都有实践过。为此,有过成功喜悦、也有过苦逼的岁月。又一个周末,独自坐在办公室里,品着苦味的菊花茶。室外红尘喧嚣不止,室内孤寂异常。在这百无聊赖的周末,想着,做点儿什么,来证明自己不曾辜负这轻浮的繁城之色。(闲言碎语)
接下来,我想介绍的才是我们今晚的主题--Sync Framework同步框架。
很多朋友,看到这个或许并不陌生吧。肯定也会有很多朋友不曾留意她。今天,就让我简单的给大家介绍+演示下。
文章的开头,了解了什么是Sync Framework同步框架后,用处自然不必多少。接下来,就是了解他有什么好处?
下面这段话,同样摘自微软Sync Framework同步框架。
同步在理论上十分简单:它是在适当时间在两个或更多参与者(例如计算机、设备或服务)之间复制正确的数据集的过程。但是,实践起来却十分困难。其中的难点包括:集成不同类型的数据;检测到并解决冲突;与能力不尽相同或者要求数据的不同子集的参与者合作;以及处理不可靠的网络。同步可能对于公司成功起着至关重要的作用,但许多开发人员不知道如何编写满足其公司需要的同步解决方案。而 Sync Framework 可助您一臂之力。
Sync Framework 将为要求数据同步的多种不同形式的应用程序带来好处。 例如,个人信息管理 (PIM) 软件可以使用 Sync Framework 将 PIM 数据更新信息传播到所有参与者。共享诸如文档等数据的业务应用程序可以使用 Sync Framework 确保所有团队成员接收文档更新并正确处理所有并发更新冲突。在个人计算机上运行并管理移动设备上的介质的介质管理软件可以使用 Sync Framework 轻松地在设备上执行相应更新。
Sync Framework 通过提供可供开发人员选择的一组组件来满足这些应用程序的要求。某些组件同步特定类型的数据,而其他组件可用于创建完全自定义的解决方案。Sync Framework 为同步提供功能强大的设计和灵活的方法。设计带来的好处如下:
-
可用于将多个数据源集成到一个同步生态系统中的可扩展模型。
-
用于所有组件的一个托管 API,以及用于所选组件的一个本机 API。
-
用于自动和自定义解决方案的冲突解决。
-
用于同步数据的子集(例如仅限包含图像的那些文件)的筛选器。
-
紧凑、高效的元数据模型,使您可为几乎所有参与者实现同步,同时不会对数据存储区进行重大变更:
-
任何数据存储区
将同步添加到多种应用程序、服务和设备。
-
任何数据类型
引入要同步的新数据类型。利用独有的基于元数据的同步技术来同步任何类型的数据。
-
任何协议
使用现有的体系结构和协议来同步数据。通过传输不可知的体系结构,允许将同步集成到多种协议中,包括无线设备和嵌入设备。
-
任何网络配置
在真正的对等或中心辐射型配置中为您的应用程序、设备和服务实现同步。轻松地从网络中断中恢复。通过高效选择要同步的变更减少网络通信量。
-
Sync Framework文档对于它的用法,介绍的相当详细。
如果想使用它,那我们就要去官方下载Sync Framework SDK。在这里,本人电脑上已经安装了Sync Framework 2.1(x86/x64)都装了。
在这里,我们试想这样一个场景。我们用C#开发了一个桌面软件。为了存储数据,我们采用了了微软的嵌入式数据库SQL SERVER Compact。至于有的朋友说,为什么不用SQLLit,这不是我们今天讨论的话题。当用户在不联网的请情况下,我们将数据保存到本地,当用户连接上网络后,为了某些需求,我们需要把这段时间,用户脱机的一些数据,同步更新到服务端。
假设,服务端,我们用的是SQLSERVER 2008 R2。接下来,我在服务端,创建了一个数据库TestA,在TestA中,又创建了ext_DoRecord表,用于存储用户的某些操作记录。
接着,我又创建一个控制台应用程序。根据Sync Framework文档的要求,我们需要引入
using Microsoft.Synchronization; using Microsoft.Synchronization.Data; using Microsoft.Synchronization.Data.SqlServer; using Microsoft.Synchronization.Data.SqlServerCe;
using System.Data.SqlServerCe;
这些命名空间。
来看看我们的控制台小程序吧!代码如下:
1、首先,我们需要进行服务端的配置
/// <summary> /// 配置服务端 /// </summary> static void ConfigureServer() { #region 1、配置服务端 SqlConnection serverConn = new SqlConnection("Data Source=localhost; Initial Catalog=TestA; Integrated Security=True"); //1、我们定义一个作用域,名字叫做,ext_DoRecordScope DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription("ext_DoRecordScope"); //2、从服务端,获取要同步的表描述 DbSyncTableDescription tableDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable("ext_DoRecord", serverConn); //3、把表,加入作用域 scopeDesc.Tables.Add(tableDesc); //4、初始化服务度作用域 SqlSyncScopeProvisioning serverProvision = new SqlSyncScopeProvisioning(serverConn, scopeDesc); //5、如果表已经存在,则跳过创建表的步骤 serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip); //6、启动代理 serverProvision.Apply(); #endregion 1、配置服务端 }
2、同样,我们为客户端创建一个配置函数。
/// <summary> /// 配置SQL Compact客户端 /// </summary> static void ConfigureClient() { SqlCeEngine sce = new SqlCeEngine(dbconnection); if (!System.IO.File.Exists(db_file)) sce.CreateDatabase();//创建库 // create a connection to the SyncCompactDB database SqlCeConnection clientConn = new SqlCeConnection(dbconnection); SqlConnection serverConn = new SqlConnection("Data Source=localhost; Initial Catalog=TestA; Integrated Security=True"); //配置同步作用域 DbSyncScopeDescription scopeDesc = SqlSyncDescriptionBuilder.GetDescriptionForScope("ext_DoRecordScope", serverConn); // 客户端代理 SqlCeSyncScopeProvisioning clientProvision = new SqlCeSyncScopeProvisioning(clientConn, scopeDesc); //启动代理 clientProvision.Apply(); }
3、最后,我们需要一个同步方法。
/// <summary> /// 同步数据 /// </summary> static void Sync() { string strDatabaseFile = @"Data Source='" + db_file + "'"; //zao for (var i = 0; i < 10; i++) { string strInsertCommand = "INSERT INTO ext_DoRecord(ID,UserID) VALUES('" + Guid.NewGuid() + "','" + Guid.NewGuid() + "');"; DbSqlCompactHelper.ExecuteNonQuery(strInsertCommand, null, strDatabaseFile); } //创建客户端链接 SqlCeConnection clientConn = new SqlCeConnection(strDatabaseFile); // 创建发布 SqlConnection serverConn = new SqlConnection("Data Source=localhost; Initial Catalog=TestA; Integrated Security=True"); //创建同步定位 SyncOrchestrator syncOrchestrator = new SyncOrchestrator(); //SQL Compact引擎 SqlCeEngine se = new SqlCeEngine(strDatabaseFile); // 设置本地作用域提供服务 syncOrchestrator.LocalProvider = new SqlCeSyncProvider("ext_DoRecordScope", clientConn); //设置远程服务作用域 syncOrchestrator.RemoteProvider = new SqlSyncProvider("ext_DoRecordScope", serverConn); //设置上传作用域 syncOrchestrator.Direction = SyncDirectionOrder.Upload; // 绑定本地同步失败时,发生事件 ((SqlCeSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(Program_ApplyChangeFailed); //执行同步 SyncOperationStatistics syncStats = syncOrchestrator.Synchronize(); //打印同步统计信息 Console.WriteLine("启动时间: " + syncStats.SyncStartTime); Console.WriteLine("总计上传数据: " + syncStats.UploadChangesTotal); Console.WriteLine("总计下载数据: " + syncStats.DownloadChangesTotal); Console.WriteLine("完成时间: " + syncStats.SyncEndTime); Console.WriteLine(String.Empty); }
在这里需要说一下,我们在启动程序的时候,首先要对服务端进行配置,也就是说先调用ConfigureServer。配置成功后,你会发现,在服务端的数据库TestA中,多了几张表。效果如下:
这些都是同步时的一些配置信息。其次,再进行客户端的配置,配置完成后,同样在客户端的数据库中,会多出一些类似这样的表来。
接下来,让我们看一看东风吧(万事俱备)。
在同步方法中,我用一个for循环,为客户端创建了10条数据。另外,我们的目的是,要把客户端的数据同步到服务端。在这里是单项的,也就是Upload数据。Sync Framework支持上传下载双向同步。
运行我们的控制台程序,跑跑看!
在看看数据库中,是否多了数据。
在这个过程中,可能会遇到的问题:
1、检索 COM 类工厂中 CLSID 为 {EC413D66-6221-4EBB-AC55-4900FB321011} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 ...
(这是由于未正确安装Sync Framework或,程序编译时x64和x86所导致的兼容问题)
2、System.Data.SqlServerCe.dll4.0和 System.Data.SqlServerCe.dll3.5.1的兼容问题。
(这个相对好解决,只要找到对应的dll,就可以了。)
至此,我们的Sync Framework同步框架演示程序,已经告一段落。如果想了解更多,请继续关注我的博客:)。