我曾经在类似的N-Tier偶尔连接客户端中使用过Microsoft Sync Framework,效果很好。它自我更新以来已经有所改进,但我认为它仍然符合您的要求。
WCF
通过WCF运行良好,这就是我们使用的方式。(
如何配置N-Tier同步)
应具备增量同步功能
同步服务非常擅长此项任务,但您可能需要将时间戳添加到同步表中。您的客户端数据库(在我的情况下是SQL Server CE数据库)保存了上次同步时使用的最后时间戳,然后在下一次同步期间使用该时间戳获取之后发生更改的所有内容。
可以将更改推送到服务器
同样,我们也这么做了。有许多钩子可提供自定义逻辑以验证数据。
离线访问/存储信息
在完全断开的情况下正常工作(前提是用户已经同步了他们的数据)。请参见离线场景。
完全重新同步的可能性(损坏的缓存或新计算机)
客户端数据库保存所有同步信息(如果您想要,可以将知识放到服务器上,了解客户端已同步的内容)。如果删除本地数据库,则客户端将进行完全同步。
服务器端的数据提供程序是Entity Framework
这不是我使用它的方式,但同步提供程序是完全可定制的。我们曾经考虑过使用NHibernate,但请问为什么要这样做。开箱即用的Sync Services将允许您使用存储过程或直接表查询推送和拉取数据。这非常容易设置,并且由于您可能正在使用大量数据,因此运行非常快速,并且数据很容易在WCF边界上进行同步(尽管我们从xml格式化程序切换到二进制格式化程序以获得更好的性能)。
我们发现的是,尽管我们在服务器上使用了实体,但这些实体在客户端上并不一定有意义,因此我们在客户端上有了一整套新的实体。这也意味着我们在存储过程中剥离了客户端不需要的数据。同样,这非常容易,您无需涉及 ADO.net。然后,一旦数据在客户端上,我们使用 NHibernate 来读写本地数据库。
为 Microsoft Sync Framework 构建自定义同步提供程序
我需要重用当前的自定义身份验证
如果您指的是 WCF 自定义身份验证,则是的,因为我们有自己的 WCF 自定义安全令牌,而且没有任何影响。
额外奖励:某些类型具有特殊的同步(例如,我有一个包含小文件的数据库,但在客户端上,文件必须直接放在文件夹中)
简短的答案是我不知道,因为新框架中有一个文件同步提供程序,我没有使用过,但您还有两个选项。
- 在客户端同步期间,您可以实际上进入数据将被放入表中的点,并有机会将二进制数据提取出来并将其写入文件系统而不是数据库。
- 从同步中排除文件二进制数据,然后使用另一个进程在同步之后拉取此数据。由于我们正在拉取的软件包相当大,因此我们使用初始同步来拉取“元数据”,然后我们使用称为BITS的东西(它是Windows的一部分)异步地拉取文件。
Microsoft Sync Framework文件同步提供程序介绍
[更新]
回答评论中提出的问题。
My application should works for different users on the same computer. In my case, I was using the isolated storage to guarantee that they works in a different location, is this possible with SQL Server CE?
Our application was deployed via ClickOnce which would provide a separate installation of the application for each user but I don't think that is what is being asked. SQL CE is just an in memory database, you point the SqlCeEngine
at the database file you want to load so isolated storage is perfect.
As far as I know, SQL Server CE is like SQLite, how do you manage the schema creation?
You can let Snyc Services create the database schema for you if you want and that will be good enough to get you going but in the long run you are probably going to have to change the schema at some point. This will probably be when you do an upgrade so you are better of thinking about it early on. I dealt with this by not thinking of the database as belonging to sync services but as something sync services is told it can use.
When our application started up it did some house keeping like creating the database if it didn't exist or running database scripts if the application had just been upgraded.
Do you know if there is somewhere an example of class implementation for this N-tier sync? I need to saw what interfaces I've to implement.
The current stable release is 2.1 and I was using it just as 2.0 came out so all my work was in 1.0. Here is a link to the Microsoft Sync Framework 2.1 api on MSDN. I had to use the 1.0 docs to find the examples that I used to drive out our WCF interface so I don't know how far things have changed but you can use this to start with which defines the interface as this:
[ServiceContract]
public interface IServiceForSync
{
[OperationContract()]
SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession);
[OperationContract()]
SyncContext GetChanges(SyncGroupMetadata groupMetadata, SyncSession syncSession);
[OperationContract()]
SyncSchema GetSchema(Collection<string> tableNames, SyncSession syncSession);
[OperationContract()]
SyncServerInfo GetServerInfo(SyncSession syncSession);
}
I suppose it's one service per data type?
不,正如您从上面看到的,只有一个服务。同步的内容取决于您在服务器上公开的内容以及客户端想要参与的内容。例如,我们有两个客户端,其中一个仅对数据的一小部分感兴趣,并且仅参与同步几个表格(称为SyncTable
),而另一个则同步所有表格。
还有一个SyncGroup
的概念,它们由应该作为一个事务持久化的相关更改组成,因为它们都是相关的,即如果其中一个失败,则全部失败。您还可以单独同步组,而无需同步所有内容。
- 我可以仅同步与用户相关的数据吗?
当您进行同步时,需要传递一个
SyncParameter
,其中包含可用于过滤返回给客户端的数据的值。
如何:筛选行和列。