微软同步框架入门之五--使用WCF同步远程数据
生活随笔
收集整理的這篇文章主要介紹了
微软同步框架入门之五--使用WCF同步远程数据
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在之前介紹的兩個DEMO中,鏈接遠程服務器所使用的方式都是通過數據庫鏈接串。雖然可以簡單的實現所期望的數據同步功能,但這樣做有兩個問題:
??? 1.不適合進行分布式布署.
?? ?
??? 2.安全方面存在問題,因為在客戶端會持有遠程數據庫服務器的鏈接帳號。
?? ?
???? 因為這兩個問題,導致了今天所要說的內容。當然在MSF中是支持采用WCF方式來進行遠程數據訪問的,而且WCF不僅可以用于數據同步,還可以進行文件同步(會在后續章節中進行介紹)。
???? 好了,費話少說,開始今天的正文吧。
?? ?
???? 下面簡要介紹一下今天DEMO的一個具體開發流程。
?? ?
???? 首先我們采用我在第二篇文章中所說的方式,用同步設計向導創建一個同步增量的MSF 對象,將其名稱命名為:WcfSyncData.sync。
???? 在生成相應的DataSet類(WcfDataSet.xsd)文件之后,我們通過從“文件”-->"添加"-->"新建項目"來構造一個WCF服務庫,并將其命名為WcfSyncService。這樣在我們的解決方案中就包含了兩個項目,一個是我們的同步DEMO,一個就是新建的WCF服務項目。
??? ? 接下來我們在DEMO項目中的WcfSyncData.sync文件上雙擊,在彈出的“配置數據同步”窗口中的“服務器項目位置”處的下拉列表中就可以看出我們剛才新建的 WCFSyncService項,我們選擇它并單擊確定即可,如下圖所示:
???? 這樣我們在看WcfSyncService項目中就會多出幾個文件,它們是:
???? WcfSyncData.Server.Sync
???? WcfSyncData.Server.Designer.cs
???? WcfSyncData.Server.SyncContract.cs
?? ?
???? 其中的WcfSyncData.Server.Designer.cs內容就是以前在DEMO項目中的WcfSyncData.Designer.cs中的關于服務端SyncAdapter(數據庫訪問操作,SQL命令等)部分的內容,這里設計器自動將這部分代碼遷移到了當前的WCF項目中,代碼如下(相應的生成類內容分析參見這篇文章):
?? ?
Code
public?partial?class?dnt_spacelinksSyncAdapter?:?Microsoft.Synchronization.Data.Server.SyncAdapter?{
????
????partial?void?OnInitialized();
????
????public?dnt_spacelinksSyncAdapter()?{
????????this.InitializeCommands();
????????this.InitializeAdapterProperties();
????????this.OnInitialized();
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeCommands()?{
????????//?dnt_spacelinksSyncTableInsertCommand?command.
????????this.InsertCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.InsertCommand.CommandText?=?@"?SET?IDENTITY_INSERT?dbo.dnt_spacelinks?ON?INSERT?INTO?dbo.dnt_spacelinks?([linkid],?[userid],?[linktitle],?[linkurl],?[de.ion],?[LastEditDate],?[CreationDate])?VALUES?(@linkid,?@userid,?@linktitle,?@linkurl,?@de.ion,?@LastEditDate,?@CreationDate)?SET?@sync_row_count?=?@@rowcount?SET?IDENTITY_INSERT?dbo.dnt_spacelinks?OFF?";
????????this.InsertCommand.CommandType?=?System.Data.CommandType.Text;
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@userid",?System.Data.SqlDbType.Int));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linktitle",?System.Data.SqlDbType.NVarChar));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkurl",?System.Data.SqlDbType.VarChar));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@de.ion",?System.Data.SqlDbType.NVarChar));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@LastEditDate",?System.Data.SqlDbType.DateTime));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@CreationDate",?System.Data.SqlDbType.DateTime));
????????System.Data.SqlClient.SqlParameter?insertcommand_sync_row_countParameter?=?new?System.Data.SqlClient.SqlParameter("@sync_row_count",?System.Data.SqlDbType.Int);
????????insertcommand_sync_row_countParameter.Direction?=?System.Data.ParameterDirection.Output;
????????this.InsertCommand.Parameters.Add(insertcommand_sync_row_countParameter);
????????//?dnt_spacelinksSyncTableDeleteCommand?command.
????????this.DeleteCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.DeleteCommand.CommandText?=?"DELETE?FROM?dbo.dnt_spacelinks?WHERE?([linkid]?=?@linkid)?AND?(@sync_force_write?"?+
????????????"=?1?OR?([LastEditDate]?<=?@sync_last_received_anchor))?SET?@sync_row_count?=?@@r"?+
????????????"owcount";
????????this.DeleteCommand.CommandType?=?System.Data.CommandType.Text;
????????this.DeleteCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????this.DeleteCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_force_write",?System.Data.SqlDbType.Bit));
????????this.DeleteCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????System.Data.SqlClient.SqlParameter?deletecommand_sync_row_countParameter?=?new?System.Data.SqlClient.SqlParameter("@sync_row_count",?System.Data.SqlDbType.Int);
????????deletecommand_sync_row_countParameter.Direction?=?System.Data.ParameterDirection.Output;
????????this.DeleteCommand.Parameters.Add(deletecommand_sync_row_countParameter);
????????//?dnt_spacelinksSyncTableUpdateCommand?command.
????????this.UpdateCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.UpdateCommand.CommandText?=?@"UPDATE?dbo.dnt_spacelinks?SET?[userid]?=?@userid,?[linktitle]?=?@linktitle,?[linkurl]?=?@linkurl,?[de.ion]?=?@de.ion,?[LastEditDate]?=?@LastEditDate,?[CreationDate]?=?@CreationDate?WHERE?([linkid]?=?@linkid)?AND?(@sync_force_write?=?1?OR?([LastEditDate]?<=?@sync_last_received_anchor))?SET?@sync_row_count?=?@@rowcount";
????????this.UpdateCommand.CommandType?=?System.Data.CommandType.Text;
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@userid",?System.Data.SqlDbType.Int));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linktitle",?System.Data.SqlDbType.NVarChar));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkurl",?System.Data.SqlDbType.VarChar));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@de.ion",?System.Data.SqlDbType.NVarChar));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@LastEditDate",?System.Data.SqlDbType.DateTime));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@CreationDate",?System.Data.SqlDbType.DateTime));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_force_write",?System.Data.SqlDbType.Bit));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????System.Data.SqlClient.SqlParameter?updatecommand_sync_row_countParameter?=?new?System.Data.SqlClient.SqlParameter("@sync_row_count",?System.Data.SqlDbType.Int);
????????updatecommand_sync_row_countParameter.Direction?=?System.Data.ParameterDirection.Output;
????????this.UpdateCommand.Parameters.Add(updatecommand_sync_row_countParameter);
????????//?dnt_spacelinksSyncTableSelectConflictDeletedRowsCommand?command.
????????this.SelectConflictDeletedRowsCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectConflictDeletedRowsCommand.CommandText?=?"SELECT?[linkid],?[DeletionDate]?FROM?dbo.dnt_spacelinks_Tombstone?WHERE?([linkid]"?+
????????????"?=?@linkid)";
????????this.SelectConflictDeletedRowsCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectConflictDeletedRowsCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????//?dnt_spacelinksSyncTableSelectConflictUpdatedRowsCommand?command.
????????this.SelectConflictUpdatedRowsCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectConflictUpdatedRowsCommand.CommandText?=?"SELECT?[linkid],?[userid],?[linktitle],?[linkurl],?[de.ion],?[LastEditDate],"?+
????????????"?[CreationDate]?FROM?dbo.dnt_spacelinks?WHERE?([linkid]?=?@linkid)";
????????this.SelectConflictUpdatedRowsCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectConflictUpdatedRowsCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????//?dnt_spacelinksSyncTableSelectIncrementalInsertsCommand?command.
????????this.SelectIncrementalInsertsCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectIncrementalInsertsCommand.CommandText?=?"SELECT?[linkid],?[userid],?[linktitle],?[linkurl],?[de.ion],?[LastEditDate],"?+
????????????"?[CreationDate]?FROM?dbo.dnt_spacelinks?WHERE?([CreationDate]?>?@sync_last_recei"?+
????????????"ved_anchor?AND?[CreationDate]?<=?@sync_new_received_anchor)";
????????this.SelectIncrementalInsertsCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectIncrementalInsertsCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????this.SelectIncrementalInsertsCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_new_received_anchor",?System.Data.SqlDbType.DateTime));
????????//?dnt_spacelinksSyncTableSelectIncrementalDeletesCommand?command.
????????this.SelectIncrementalDeletesCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectIncrementalDeletesCommand.CommandText?=?"SELECT?[linkid],?[DeletionDate]?FROM?dbo.dnt_spacelinks_Tombstone?WHERE?(@sync_in"?+
????????????"itialized?=?1?AND?[DeletionDate]?>?@sync_last_received_anchor?AND?[DeletionDate]"?+
????????????"?<=?@sync_new_received_anchor)";
????????this.SelectIncrementalDeletesCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectIncrementalDeletesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_initialized",?System.Data.SqlDbType.Bit));
????????this.SelectIncrementalDeletesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????this.SelectIncrementalDeletesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_new_received_anchor",?System.Data.SqlDbType.DateTime));
????????//?dnt_spacelinksSyncTableSelectIncrementalUpdatesCommand?command.
????????this.SelectIncrementalUpdatesCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectIncrementalUpdatesCommand.CommandText?=?@"SELECT?[linkid],?[userid],?[linktitle],?[linkurl],?[de.ion],?[LastEditDate],?[CreationDate]?FROM?dbo.dnt_spacelinks?WHERE?([LastEditDate]?>?@sync_last_received_anchor?AND?[LastEditDate]?<=?@sync_new_received_anchor?AND?[CreationDate]?<=?@sync_last_received_anchor)";
????????this.SelectIncrementalUpdatesCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectIncrementalUpdatesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????this.SelectIncrementalUpdatesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_new_received_anchor",?System.Data.SqlDbType.DateTime));
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeAdapterProperties()?{
????????this.TableName?=?"dnt_spacelinks";
????}
}
public?partial?class?WcfSyncDataServerSyncProvider?:?Microsoft.Synchronization.Data.Server.DbServerSyncProvider?{
????
????private?dnt_spacelinksSyncAdapter?_dnt_spacelinksSyncAdapter;
????
????partial?void?OnInitialized();
????
????public?WcfSyncDataServerSyncProvider()?{
????????string?connectionString?=?global::WcfSyncService.Properties.Settings.Default.ServertestConnectionString;
????????this.InitializeConnection(connectionString);
????????this.InitializeSyncAdapters();
????????this.InitializeNewAnchorCommand();
????????this.OnInitialized();
????}
????
????public?WcfSyncDataServerSyncProvider(string?connectionString)?{
????????this.InitializeConnection(connectionString);
????????this.InitializeSyncAdapters();
????????this.InitializeNewAnchorCommand();
????????this.OnInitialized();
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????public?dnt_spacelinksSyncAdapter?dnt_spacelinksSyncAdapter?{
????????get?{
????????????return?this._dnt_spacelinksSyncAdapter;
????????}
????????set?{
????????????this._dnt_spacelinksSyncAdapter?=?value;
????????}
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeConnection(string?connectionString)?{
????????this.Connection?=?new?System.Data.SqlClient.SqlConnection(connectionString);
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeSyncAdapters()?{
????????//?Create?SyncAdapters.
????????this._dnt_spacelinksSyncAdapter?=?new?dnt_spacelinksSyncAdapter();
????????this.SyncAdapters.Add(this._dnt_spacelinksSyncAdapter);
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeNewAnchorCommand()?{
????????//?selectNewAnchorCmd?command.
????????this.SelectNewAnchorCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectNewAnchorCommand.CommandText?=?"Select?@sync_new_received_anchor?=?GETUTCDATE()";
????????this.SelectNewAnchorCommand.CommandType?=?System.Data.CommandType.Text;
????????System.Data.SqlClient.SqlParameter?selectnewanchorcommand_sync_new_received_anchorParameter?=?new?System.Data.SqlClient.SqlParameter("@sync_new_received_anchor",?System.Data.SqlDbType.DateTime);
????????selectnewanchorcommand_sync_new_received_anchorParameter.Direction?=?System.Data.ParameterDirection.Output;
????????this.SelectNewAnchorCommand.Parameters.Add(selectnewanchorcommand_sync_new_received_anchorParameter);
????}
}
?? ?
???? 除此之外,設計器向導還為我們自動生成了WcfSyncData.Server.SyncContract.cs文件,這個就是相應的WCF服務類文件,里面的內容定義如下:
? public?partial?class?WcfSyncDataSyncService?:?object,?IWcfSyncDataSyncContract?{
????????
????????private?WcfSyncDataServerSyncProvider?_serverSyncProvider;
????????
????????public?WcfSyncDataSyncService()?{
????????????this._serverSyncProvider?=?new?WcfSyncDataServerSyncProvider();
????????}
????????
????????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????????public?virtual?SyncContext?ApplyChanges(SyncGroupMetadata?groupMetadata,?DataSet?dataSet,? SyncSession?syncSession)?{
????????????return?this._serverSyncProvider.ApplyChanges(groupMetadata,?dataSet,?syncSession);
????????}
????????
????????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????????public?virtual?SyncContext?GetChanges(SyncGroupMetadata?groupMetadata,?SyncSession?syncSession)?{
????????????return?this._serverSyncProvider.GetChanges(groupMetadata,?syncSession);
????????}
????????
????????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????????public?virtual?SyncSchema?GetSchema(Collection<string>?tableNames,?SyncSession?syncSession)?{
????????????return?this._serverSyncProvider.GetSchema(tableNames,?syncSession);
????????}
????????
????????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????????public?virtual?SyncServerInfo?GetServerInfo(SyncSession?syncSession)?{
????????????return?this._serverSyncProvider.GetServerInfo(syncSession);
????????}
????}
????
????[ServiceContractAttribute()]
????public?interface?IWcfSyncDataSyncContract?{
????????
????????[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);
????}
?? ?
???? 按照該文件上方提供的關于app.config配置結點信息,我們將相應的服務配置信息定義如下,首先是services 節中:
?? ?
<service?name="WcfSyncService.WcfSyncDataSyncService"
??????????????behaviorConfiguration="WcfSyncService.WcfSyncDataSyncServiceBehavior">
??<host>
????<baseAddresses>
??????<add?baseAddress?="http://localhost:8731/Design_Time_Addresses/WcfSyncService/WcfSyncDataSyncService/"/>
????</baseAddresses>
??</host>
??<endpoint?address?=""?binding="wsHttpBinding"?contract="WcfSyncService.IWcfSyncDataSyncContract">
????<identity>
??????<dns?value="localhost"/>
????</identity>
??</endpoint>
??<endpoint?address="mex"?binding="mexHttpBinding"?contract="IMetadataExchange"?/>
</service>
?
???? 然后是serviceBehaviors 節中:
???
?????<behavior?name="WcfSyncService.WcfSyncDataSyncServiceBehavior">
??????????<serviceMetadata?httpGetEnabled="True"?/>
??????????<serviceDebug?includeExceptionDetailInFaults="False"?/>
?????</behavior>?
?? ?
???? 這樣配置完成后,我們將當前WCF作為啟動項目并編譯運行,然后將相應的服務地址鏈接信息拷貝出來,
然后在DEMO項目中以“添加服務引用”的方式添加進來。
???? 注:本DEMO的鏈接地址為:?? ?
???? [url]http://localhost:8731/Design_Time_Addresses/WcfSyncService/WcfSyncDataSyncService/[/url]
?? ??? ?
???? 接下來,我們只要在創建同步代理(SyncAgent)時創建相應的WCF服務(client)類實例,并將其綁定到代理類的 RemoteProvider 屬性上即可,相應代碼如下(位于WcfSyncForm.cs文件中):
WcfSyncDataSyncAgent?syncAgent?=???new?WcfSyncDataSyncAgent(new?MSF_WinFormDemo.WcfServiceSync.WcfSyncDataSyncContractClient());
syncAgent.dnt_spacelinks.SyncDirection?=?Microsoft.Synchronization.Data.SyncDirection.Bidirectional;
syncAgent.Synchronize();?//將本地數據同步到遠程數據服務器
?? ?
???? 大家注意看上面的new MSF_WinFormDemo.WcfServiceSync.WcfSyncDataSyncContractClient()
即是我們在添加Web服務引用時生成的服務代理類。通過調用WcfSyncDataSyncAgent構造重載方法將代理類實例綁定到syncAgent實例的RemoteProvider上,相應的重載構造方法如下所示(位于DEMO項目中
的WcfSyncData.Designer.cs文件):
public?WcfSyncDataSyncAgent(object?remoteSyncProviderProxy)?{
????this.InitializeSyncProviders();
????this.InitializeSyncTables();
????this.RemoteProvider?=
??????????new?Microsoft.Synchronization.Data.ServerSyncProviderProxy(remoteSyncProviderProxy);
????this.OnInitialized();
}
?????? ?
???? 而接下來的其余代碼就與之前我寫過的那兩個DEMO中的代碼沒有什么區別了。看來采用WCF方式進行遠程數據訪問很容易,主要就是將服務引用到本地,并進行同步代理RemoteProvider屬性的相關綁定即可。?? ???? 到今天為止,有關于MSF中Sync Service for ADO.NET的內容就要先告一段落了。從下一篇文章開始,我會介紹在MSF中如何進行文件同步(File Sync),對這方面感興趣的朋友敬請留意。? ?
? ?
? ?
???? 好了,今天的內容就先到這里了:)
???? 原文鏈接:[url]http://www.cnblogs.com/daizhj/archive/2008/11/20/1337245.html[/url]
???? 作者: daizhj, 代震軍
???? Tags: 微軟同步框架,ado.net,sqlce,wcf
???? 網址: [url]http://daizhj.cnblogs.com/[/url]
???? DEMO下載,請點擊這里:)
??? 1.不適合進行分布式布署.
?? ?
??? 2.安全方面存在問題,因為在客戶端會持有遠程數據庫服務器的鏈接帳號。
?? ?
???? 因為這兩個問題,導致了今天所要說的內容。當然在MSF中是支持采用WCF方式來進行遠程數據訪問的,而且WCF不僅可以用于數據同步,還可以進行文件同步(會在后續章節中進行介紹)。
???? 好了,費話少說,開始今天的正文吧。
?? ?
???? 下面簡要介紹一下今天DEMO的一個具體開發流程。
?? ?
???? 首先我們采用我在第二篇文章中所說的方式,用同步設計向導創建一個同步增量的MSF 對象,將其名稱命名為:WcfSyncData.sync。
???? 在生成相應的DataSet類(WcfDataSet.xsd)文件之后,我們通過從“文件”-->"添加"-->"新建項目"來構造一個WCF服務庫,并將其命名為WcfSyncService。這樣在我們的解決方案中就包含了兩個項目,一個是我們的同步DEMO,一個就是新建的WCF服務項目。
??? ? 接下來我們在DEMO項目中的WcfSyncData.sync文件上雙擊,在彈出的“配置數據同步”窗口中的“服務器項目位置”處的下拉列表中就可以看出我們剛才新建的 WCFSyncService項,我們選擇它并單擊確定即可,如下圖所示:
???? 這樣我們在看WcfSyncService項目中就會多出幾個文件,它們是:
???? WcfSyncData.Server.Sync
???? WcfSyncData.Server.Designer.cs
???? WcfSyncData.Server.SyncContract.cs
?? ?
???? 其中的WcfSyncData.Server.Designer.cs內容就是以前在DEMO項目中的WcfSyncData.Designer.cs中的關于服務端SyncAdapter(數據庫訪問操作,SQL命令等)部分的內容,這里設計器自動將這部分代碼遷移到了當前的WCF項目中,代碼如下(相應的生成類內容分析參見這篇文章):
?? ?
Code
public?partial?class?dnt_spacelinksSyncAdapter?:?Microsoft.Synchronization.Data.Server.SyncAdapter?{
????
????partial?void?OnInitialized();
????
????public?dnt_spacelinksSyncAdapter()?{
????????this.InitializeCommands();
????????this.InitializeAdapterProperties();
????????this.OnInitialized();
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeCommands()?{
????????//?dnt_spacelinksSyncTableInsertCommand?command.
????????this.InsertCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.InsertCommand.CommandText?=?@"?SET?IDENTITY_INSERT?dbo.dnt_spacelinks?ON?INSERT?INTO?dbo.dnt_spacelinks?([linkid],?[userid],?[linktitle],?[linkurl],?[de.ion],?[LastEditDate],?[CreationDate])?VALUES?(@linkid,?@userid,?@linktitle,?@linkurl,?@de.ion,?@LastEditDate,?@CreationDate)?SET?@sync_row_count?=?@@rowcount?SET?IDENTITY_INSERT?dbo.dnt_spacelinks?OFF?";
????????this.InsertCommand.CommandType?=?System.Data.CommandType.Text;
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@userid",?System.Data.SqlDbType.Int));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linktitle",?System.Data.SqlDbType.NVarChar));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkurl",?System.Data.SqlDbType.VarChar));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@de.ion",?System.Data.SqlDbType.NVarChar));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@LastEditDate",?System.Data.SqlDbType.DateTime));
????????this.InsertCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@CreationDate",?System.Data.SqlDbType.DateTime));
????????System.Data.SqlClient.SqlParameter?insertcommand_sync_row_countParameter?=?new?System.Data.SqlClient.SqlParameter("@sync_row_count",?System.Data.SqlDbType.Int);
????????insertcommand_sync_row_countParameter.Direction?=?System.Data.ParameterDirection.Output;
????????this.InsertCommand.Parameters.Add(insertcommand_sync_row_countParameter);
????????//?dnt_spacelinksSyncTableDeleteCommand?command.
????????this.DeleteCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.DeleteCommand.CommandText?=?"DELETE?FROM?dbo.dnt_spacelinks?WHERE?([linkid]?=?@linkid)?AND?(@sync_force_write?"?+
????????????"=?1?OR?([LastEditDate]?<=?@sync_last_received_anchor))?SET?@sync_row_count?=?@@r"?+
????????????"owcount";
????????this.DeleteCommand.CommandType?=?System.Data.CommandType.Text;
????????this.DeleteCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????this.DeleteCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_force_write",?System.Data.SqlDbType.Bit));
????????this.DeleteCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????System.Data.SqlClient.SqlParameter?deletecommand_sync_row_countParameter?=?new?System.Data.SqlClient.SqlParameter("@sync_row_count",?System.Data.SqlDbType.Int);
????????deletecommand_sync_row_countParameter.Direction?=?System.Data.ParameterDirection.Output;
????????this.DeleteCommand.Parameters.Add(deletecommand_sync_row_countParameter);
????????//?dnt_spacelinksSyncTableUpdateCommand?command.
????????this.UpdateCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.UpdateCommand.CommandText?=?@"UPDATE?dbo.dnt_spacelinks?SET?[userid]?=?@userid,?[linktitle]?=?@linktitle,?[linkurl]?=?@linkurl,?[de.ion]?=?@de.ion,?[LastEditDate]?=?@LastEditDate,?[CreationDate]?=?@CreationDate?WHERE?([linkid]?=?@linkid)?AND?(@sync_force_write?=?1?OR?([LastEditDate]?<=?@sync_last_received_anchor))?SET?@sync_row_count?=?@@rowcount";
????????this.UpdateCommand.CommandType?=?System.Data.CommandType.Text;
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@userid",?System.Data.SqlDbType.Int));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linktitle",?System.Data.SqlDbType.NVarChar));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkurl",?System.Data.SqlDbType.VarChar));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@de.ion",?System.Data.SqlDbType.NVarChar));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@LastEditDate",?System.Data.SqlDbType.DateTime));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@CreationDate",?System.Data.SqlDbType.DateTime));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_force_write",?System.Data.SqlDbType.Bit));
????????this.UpdateCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????System.Data.SqlClient.SqlParameter?updatecommand_sync_row_countParameter?=?new?System.Data.SqlClient.SqlParameter("@sync_row_count",?System.Data.SqlDbType.Int);
????????updatecommand_sync_row_countParameter.Direction?=?System.Data.ParameterDirection.Output;
????????this.UpdateCommand.Parameters.Add(updatecommand_sync_row_countParameter);
????????//?dnt_spacelinksSyncTableSelectConflictDeletedRowsCommand?command.
????????this.SelectConflictDeletedRowsCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectConflictDeletedRowsCommand.CommandText?=?"SELECT?[linkid],?[DeletionDate]?FROM?dbo.dnt_spacelinks_Tombstone?WHERE?([linkid]"?+
????????????"?=?@linkid)";
????????this.SelectConflictDeletedRowsCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectConflictDeletedRowsCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????//?dnt_spacelinksSyncTableSelectConflictUpdatedRowsCommand?command.
????????this.SelectConflictUpdatedRowsCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectConflictUpdatedRowsCommand.CommandText?=?"SELECT?[linkid],?[userid],?[linktitle],?[linkurl],?[de.ion],?[LastEditDate],"?+
????????????"?[CreationDate]?FROM?dbo.dnt_spacelinks?WHERE?([linkid]?=?@linkid)";
????????this.SelectConflictUpdatedRowsCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectConflictUpdatedRowsCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@linkid",?System.Data.SqlDbType.Int));
????????//?dnt_spacelinksSyncTableSelectIncrementalInsertsCommand?command.
????????this.SelectIncrementalInsertsCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectIncrementalInsertsCommand.CommandText?=?"SELECT?[linkid],?[userid],?[linktitle],?[linkurl],?[de.ion],?[LastEditDate],"?+
????????????"?[CreationDate]?FROM?dbo.dnt_spacelinks?WHERE?([CreationDate]?>?@sync_last_recei"?+
????????????"ved_anchor?AND?[CreationDate]?<=?@sync_new_received_anchor)";
????????this.SelectIncrementalInsertsCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectIncrementalInsertsCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????this.SelectIncrementalInsertsCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_new_received_anchor",?System.Data.SqlDbType.DateTime));
????????//?dnt_spacelinksSyncTableSelectIncrementalDeletesCommand?command.
????????this.SelectIncrementalDeletesCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectIncrementalDeletesCommand.CommandText?=?"SELECT?[linkid],?[DeletionDate]?FROM?dbo.dnt_spacelinks_Tombstone?WHERE?(@sync_in"?+
????????????"itialized?=?1?AND?[DeletionDate]?>?@sync_last_received_anchor?AND?[DeletionDate]"?+
????????????"?<=?@sync_new_received_anchor)";
????????this.SelectIncrementalDeletesCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectIncrementalDeletesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_initialized",?System.Data.SqlDbType.Bit));
????????this.SelectIncrementalDeletesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????this.SelectIncrementalDeletesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_new_received_anchor",?System.Data.SqlDbType.DateTime));
????????//?dnt_spacelinksSyncTableSelectIncrementalUpdatesCommand?command.
????????this.SelectIncrementalUpdatesCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectIncrementalUpdatesCommand.CommandText?=?@"SELECT?[linkid],?[userid],?[linktitle],?[linkurl],?[de.ion],?[LastEditDate],?[CreationDate]?FROM?dbo.dnt_spacelinks?WHERE?([LastEditDate]?>?@sync_last_received_anchor?AND?[LastEditDate]?<=?@sync_new_received_anchor?AND?[CreationDate]?<=?@sync_last_received_anchor)";
????????this.SelectIncrementalUpdatesCommand.CommandType?=?System.Data.CommandType.Text;
????????this.SelectIncrementalUpdatesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_last_received_anchor",?System.Data.SqlDbType.DateTime));
????????this.SelectIncrementalUpdatesCommand.Parameters.Add(new?System.Data.SqlClient.SqlParameter("@sync_new_received_anchor",?System.Data.SqlDbType.DateTime));
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeAdapterProperties()?{
????????this.TableName?=?"dnt_spacelinks";
????}
}
public?partial?class?WcfSyncDataServerSyncProvider?:?Microsoft.Synchronization.Data.Server.DbServerSyncProvider?{
????
????private?dnt_spacelinksSyncAdapter?_dnt_spacelinksSyncAdapter;
????
????partial?void?OnInitialized();
????
????public?WcfSyncDataServerSyncProvider()?{
????????string?connectionString?=?global::WcfSyncService.Properties.Settings.Default.ServertestConnectionString;
????????this.InitializeConnection(connectionString);
????????this.InitializeSyncAdapters();
????????this.InitializeNewAnchorCommand();
????????this.OnInitialized();
????}
????
????public?WcfSyncDataServerSyncProvider(string?connectionString)?{
????????this.InitializeConnection(connectionString);
????????this.InitializeSyncAdapters();
????????this.InitializeNewAnchorCommand();
????????this.OnInitialized();
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????public?dnt_spacelinksSyncAdapter?dnt_spacelinksSyncAdapter?{
????????get?{
????????????return?this._dnt_spacelinksSyncAdapter;
????????}
????????set?{
????????????this._dnt_spacelinksSyncAdapter?=?value;
????????}
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeConnection(string?connectionString)?{
????????this.Connection?=?new?System.Data.SqlClient.SqlConnection(connectionString);
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeSyncAdapters()?{
????????//?Create?SyncAdapters.
????????this._dnt_spacelinksSyncAdapter?=?new?dnt_spacelinksSyncAdapter();
????????this.SyncAdapters.Add(this._dnt_spacelinksSyncAdapter);
????}
????
????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????private?void?InitializeNewAnchorCommand()?{
????????//?selectNewAnchorCmd?command.
????????this.SelectNewAnchorCommand?=?new?System.Data.SqlClient.SqlCommand();
????????this.SelectNewAnchorCommand.CommandText?=?"Select?@sync_new_received_anchor?=?GETUTCDATE()";
????????this.SelectNewAnchorCommand.CommandType?=?System.Data.CommandType.Text;
????????System.Data.SqlClient.SqlParameter?selectnewanchorcommand_sync_new_received_anchorParameter?=?new?System.Data.SqlClient.SqlParameter("@sync_new_received_anchor",?System.Data.SqlDbType.DateTime);
????????selectnewanchorcommand_sync_new_received_anchorParameter.Direction?=?System.Data.ParameterDirection.Output;
????????this.SelectNewAnchorCommand.Parameters.Add(selectnewanchorcommand_sync_new_received_anchorParameter);
????}
}
?? ?
???? 除此之外,設計器向導還為我們自動生成了WcfSyncData.Server.SyncContract.cs文件,這個就是相應的WCF服務類文件,里面的內容定義如下:
? public?partial?class?WcfSyncDataSyncService?:?object,?IWcfSyncDataSyncContract?{
????????
????????private?WcfSyncDataServerSyncProvider?_serverSyncProvider;
????????
????????public?WcfSyncDataSyncService()?{
????????????this._serverSyncProvider?=?new?WcfSyncDataServerSyncProvider();
????????}
????????
????????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????????public?virtual?SyncContext?ApplyChanges(SyncGroupMetadata?groupMetadata,?DataSet?dataSet,? SyncSession?syncSession)?{
????????????return?this._serverSyncProvider.ApplyChanges(groupMetadata,?dataSet,?syncSession);
????????}
????????
????????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????????public?virtual?SyncContext?GetChanges(SyncGroupMetadata?groupMetadata,?SyncSession?syncSession)?{
????????????return?this._serverSyncProvider.GetChanges(groupMetadata,?syncSession);
????????}
????????
????????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????????public?virtual?SyncSchema?GetSchema(Collection<string>?tableNames,?SyncSession?syncSession)?{
????????????return?this._serverSyncProvider.GetSchema(tableNames,?syncSession);
????????}
????????
????????[System.Diagnostics.DebuggerNonUserCodeAttribute()]
????????public?virtual?SyncServerInfo?GetServerInfo(SyncSession?syncSession)?{
????????????return?this._serverSyncProvider.GetServerInfo(syncSession);
????????}
????}
????
????[ServiceContractAttribute()]
????public?interface?IWcfSyncDataSyncContract?{
????????
????????[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);
????}
?? ?
???? 按照該文件上方提供的關于app.config配置結點信息,我們將相應的服務配置信息定義如下,首先是services 節中:
?? ?
<service?name="WcfSyncService.WcfSyncDataSyncService"
??????????????behaviorConfiguration="WcfSyncService.WcfSyncDataSyncServiceBehavior">
??<host>
????<baseAddresses>
??????<add?baseAddress?="http://localhost:8731/Design_Time_Addresses/WcfSyncService/WcfSyncDataSyncService/"/>
????</baseAddresses>
??</host>
??<endpoint?address?=""?binding="wsHttpBinding"?contract="WcfSyncService.IWcfSyncDataSyncContract">
????<identity>
??????<dns?value="localhost"/>
????</identity>
??</endpoint>
??<endpoint?address="mex"?binding="mexHttpBinding"?contract="IMetadataExchange"?/>
</service>
?
???? 然后是serviceBehaviors 節中:
???
?????<behavior?name="WcfSyncService.WcfSyncDataSyncServiceBehavior">
??????????<serviceMetadata?httpGetEnabled="True"?/>
??????????<serviceDebug?includeExceptionDetailInFaults="False"?/>
?????</behavior>?
?? ?
???? 這樣配置完成后,我們將當前WCF作為啟動項目并編譯運行,然后將相應的服務地址鏈接信息拷貝出來,
然后在DEMO項目中以“添加服務引用”的方式添加進來。
???? 注:本DEMO的鏈接地址為:?? ?
???? [url]http://localhost:8731/Design_Time_Addresses/WcfSyncService/WcfSyncDataSyncService/[/url]
?? ??? ?
???? 接下來,我們只要在創建同步代理(SyncAgent)時創建相應的WCF服務(client)類實例,并將其綁定到代理類的 RemoteProvider 屬性上即可,相應代碼如下(位于WcfSyncForm.cs文件中):
WcfSyncDataSyncAgent?syncAgent?=???new?WcfSyncDataSyncAgent(new?MSF_WinFormDemo.WcfServiceSync.WcfSyncDataSyncContractClient());
syncAgent.dnt_spacelinks.SyncDirection?=?Microsoft.Synchronization.Data.SyncDirection.Bidirectional;
syncAgent.Synchronize();?//將本地數據同步到遠程數據服務器
?? ?
???? 大家注意看上面的new MSF_WinFormDemo.WcfServiceSync.WcfSyncDataSyncContractClient()
即是我們在添加Web服務引用時生成的服務代理類。通過調用WcfSyncDataSyncAgent構造重載方法將代理類實例綁定到syncAgent實例的RemoteProvider上,相應的重載構造方法如下所示(位于DEMO項目中
的WcfSyncData.Designer.cs文件):
public?WcfSyncDataSyncAgent(object?remoteSyncProviderProxy)?{
????this.InitializeSyncProviders();
????this.InitializeSyncTables();
????this.RemoteProvider?=
??????????new?Microsoft.Synchronization.Data.ServerSyncProviderProxy(remoteSyncProviderProxy);
????this.OnInitialized();
}
?????? ?
???? 而接下來的其余代碼就與之前我寫過的那兩個DEMO中的代碼沒有什么區別了。看來采用WCF方式進行遠程數據訪問很容易,主要就是將服務引用到本地,并進行同步代理RemoteProvider屬性的相關綁定即可。?? ???? 到今天為止,有關于MSF中Sync Service for ADO.NET的內容就要先告一段落了。從下一篇文章開始,我會介紹在MSF中如何進行文件同步(File Sync),對這方面感興趣的朋友敬請留意。? ?
? ?
? ?
???? 好了,今天的內容就先到這里了:)
???? 原文鏈接:[url]http://www.cnblogs.com/daizhj/archive/2008/11/20/1337245.html[/url]
???? 作者: daizhj, 代震軍
???? Tags: 微軟同步框架,ado.net,sqlce,wcf
???? 網址: [url]http://daizhj.cnblogs.com/[/url]
???? DEMO下載,請點擊這里:)
轉載于:https://blog.51cto.com/daizhj/124354
總結
以上是生活随笔為你收集整理的微软同步框架入门之五--使用WCF同步远程数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET操作简单的xml,增删改查
- 下一篇: 删除VS.NET起始页上项目名称的方法.