2014-04-30 22 views
1

我想創建一個Windows應用程序使用VS 2010中的C#將同步兩個數據庫,其中一個數據庫是本地機器和另一臺服務器上。這是我的示例代碼。同步SQL Server 2008 R2(在本地服務器上運行)與Microsoft SQL服務器(在Plesk面板服務器數據庫上運行)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data.SqlClient; 
using Microsoft.Synchronization; 
using Microsoft.Synchronization.Data; 
using Microsoft.Synchronization.Data.SqlServer; 
using Microsoft.Synchronization.Data.SqlServerCe; 

namespace ExecuteExpressSync 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      SqlConnection clientConn = new SqlConnection(@" Data Source=...; Initial Catalog= SqlServerSyncDb; Network Library=;Connection Timeout=15;Packet Size=4096;Integrated Security=no;User ID=.....;Password=....;Encrypt=no;"); 

      SqlConnection serverConn = new SqlConnection("Data Source=(local); Initial Catalog=SyncDB; Integrated Security=True"); 


      var providerl = new SqlSyncProvider("scopel", serverConn); 
      var provider2 = new SqlSyncProvider("scopel", clientConn); 

      // corvfig 

      PrepareServerForProvisioning(providerl); 

      PrepareClientForProvisioning(provider2, serverConn); 

      //sync 

      SyncOrchestrator sync = new SyncOrchestrator(); 
      sync.LocalProvider = providerl; 
      sync.RemoteProvider = provider2; 

      //((SqlCeSyncProvider)sync.LocalProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(Program_ApplyChangeFailed); 

      SyncOperationStatistics syncStats = sync.Synchronize(); 




      // print statistics 
      Console.WriteLine("Start Time: " + syncStats.SyncStartTime); 
      Console.WriteLine("Total Changes Uploaded: " + syncStats.UploadChangesTotal); 
      Console.WriteLine("Total Changes Downloaded: " + syncStats.DownloadChangesTotal); 
      Console.WriteLine("Complete Time: " + syncStats.SyncEndTime); 
      Console.WriteLine(String.Empty); 
     } 

     static void Program_ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e) 
     { 
      // display conflict type 
      Console.WriteLine(e.Conflict.Type); 

      // display error message 
      Console.WriteLine(e.Error); 
     } 

     private static void PrepareServerForProvisioning(SqlSyncProvider provider) 
     { 

      SqlConnection connection = (SqlConnection)provider.Connection; 

      SqlSyncScopeProvisioning config = new SqlSyncScopeProvisioning(connection); 

      if (!config.ScopeExists(provider.ScopeName)) 
      { 

       DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription(provider.ScopeName); 

       scopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable("Products", connection)); 
       scopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable("Orders", connection)); 

       config.PopulateFromScopeDescription(scopeDesc); 

       config.SetCreateTableDefault(DbSyncCreationOption.CreateOrUseExisting); 
       config.Apply(); 

      } 

     } 

     private static void PrepareClientForProvisioning(SqlSyncProvider provider, SqlConnection sourceConnection) 
     { 

      SqlSyncScopeProvisioning config = new SqlSyncScopeProvisioning((SqlConnection)provider.Connection); 

      if (!config.ScopeExists(provider.ScopeName)) 
      { 

       DbSyncScopeDescription scopeDesc = SqlSyncDescriptionBuilder.GetDescriptionForScope(provider.ScopeName, sourceConnection); 
       config.PopulateFromScopeDescription(scopeDesc); 
       config.Apply(); 

      } 

     } 

    } 
} 

當我在同一臺機器上運行的兩個數據庫上使用相同的代碼時,它完美地工作。但是,當我使用plesk面板服務器數據庫時出現錯誤,說您的數據庫沒有配置。當我打開服務器數據庫時,我看到表已創建,但沒有數據。另一件事是,每當我試圖查看錶格數據時,它會說「索引超出數組[Microsoft.SqlServer.Smo]」。

請建議做些什麼。在此先感謝

+1

在您的plesk面板數據庫中,在哪個架構下創建了Sync Fx對象(即dbo.scope_info或userx.scope_info?) – JuneT

+0

它是userx.scope。 –

回答

0

很可能是您的Sync Fx對象正在非Dbo架構中創建。 您可以通過設置ObjectSchema屬性強制他們在設置和同步期間使用相同的模式。

在上述代碼

期間置備設置config.ObjectSchema = 「DBO」;或者你想要使用的任何模式。

在同步過程中,set provider1.ObjectSchema =「dbo」;或者你想要使用的任何模式。

關鍵在於無論您在配置中使用的架構應該在同步過程中都一樣。

如果你不不希望取消配置,設置ObjectSchema =「用戶X」(或其他模式創建對象)上同步提供指向您的Plesk面板數據庫

+0

我明白這個問題。但是無論我做什麼,我都不能將對象Schema設置爲dbo。我做了你所說的,但服務器數據庫中的對象模式仍然是userx.scope。我需要做些什麼才能正確設置對象模式。請建議。 –

+1

你有否取消你的範圍? – JuneT

+0

好吧,這是在添加對象模式之後現在發生的事情。表和跟蹤表是用dbo模式對象創建的,但其他三個表(schema_info,scope_config和scope_info)是用userx對象創建的......我想我的整個代碼是錯誤的... –

0

由於SSMS 2008 R2中的錯誤,會出現此問題。

有一些限制,多解決方法如下所述...

  1. 安裝Microsoft®SQLServer®2012快 - 你可以從這裏http://www.microsoft.com/en-us/download/details.aspx?id=29062下載。唯一的限制是支持的操作系統:Windows 7,Windows Server 2008 R2,Windows Server 2008 Service Pack 2,Windows Vista Service Pack 2.

  2. 如果您有SQL Server 2008或2008 R2安裝,您可以選擇此修補程序 - http://support.microsoft.com/kb/2459027

+0

感謝您的提示......我在我的電腦中安裝了SQL Server 2008 R2,服務器上安裝了sql server 2005.如果版本問題在這裏,我將首先選擇第二個選項。如果我成功了,我會告訴你。 –

0

在這個小項目中,我面臨的情侶問題。

  1. SSMS 2008 R2中的錯誤。
  2. 同步錯誤[未配置數據庫]。
  3. 對象模式問題。

問題1:

This problem occurred because of database version difference. My local machine Database is SQL Server 2008 r2 and plesk panel database is SQL Server 2005. 

SOLUTION:

Updated my local machine database to service pack 2. 

問題2 &問題3

Problem 2 and 3 are related. In sql server 2008 the default object schema is "dbo" [ex. dbo.tablename] and in sql server 2005 default object is "[DATABASENAME]" [ex. TestSync.tablename considering database name is TestSync]. That's why the sync error occurred. 

So to fix the problem I tried to set the object schema manually from within the code and set `config.ObjectSchema = "dbo";` in client provisioning. 

But surprisingly it didn't work at all. The plesk panel server database was still creating its default object schema [TestSync.tablename]. When I tried debugging the code I learned that if I set the object schema to "dbo" it takes a null value and really don't know the reason for that. 

SOLUTION

So I set the object schema to ".dbo". 

config.ObjectSchema = 「.dbo」;

現在它完美的工作。這裏是完整的工作代碼...

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data.SqlClient; 
using Microsoft.Synchronization; 
using Microsoft.Synchronization.Data; 
using Microsoft.Synchronization.Data.SqlServer; 
using Microsoft.Synchronization.Data.SqlServerCe; 

namespace ExecuteExpressSync 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      SqlConnection clientConn = new SqlConnection("Data Source=208.91.198.174; Initial Catalog=RANAJOYDADIGI;Integrated Security=no;User ID=RANAJOYDADIGI;Password=RANAJOYDADIGI;Encrypt=no;Integrated Security=No"); 

      SqlConnection serverConn = new SqlConnection("Data Source=(local); Initial Catalog=ANIRUDDHADHARTEST; Integrated Security=True"); 

      var providerl = new SqlSyncProvider("scopel", serverConn); 
      var provider2 = new SqlSyncProvider("scopel", clientConn); 

      // corvfig 

      PrepareServerForProvisioning(providerl); 

      PrepareClientForProvisioning(provider2, serverConn); 

      //sync 

      SyncOrchestrator sync = new SyncOrchestrator(); 

      sync.LocalProvider = providerl; 
      sync.RemoteProvider = provider2;    

      SyncOperationStatistics syncStats = sync.Synchronize(); 

      //Deprovision 

      deprovisionServerClient(providerl); 
      deprovisionServerClient(provider2); 

      serverConn.Close(); 

      serverConn.Dispose(); 

      clientConn.Close(); 

      clientConn.Dispose(); 
     }  

     private static void PrepareServerForProvisioning(SqlSyncProvider provider) 
     { 

      SqlConnection connection = (SqlConnection)provider.Connection; 

      SqlSyncScopeProvisioning config = new SqlSyncScopeProvisioning(connection); 


      if (!config.ScopeExists(provider.ScopeName)) 
      { 

       DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription(provider.ScopeName); 

       scopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable("dbo.Products", connection)); 
       scopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable("dbo.Orders", connection)); 

       config.PopulateFromScopeDescription(scopeDesc); 

       config.SetCreateTableDefault(DbSyncCreationOption.CreateOrUseExisting); 

       config.Apply(); 

      } 

     } 

     private static void PrepareClientForProvisioning(SqlSyncProvider provider, SqlConnection sourceConnection) 
     { 

      SqlSyncScopeProvisioning config = new SqlSyncScopeProvisioning((SqlConnection)provider.Connection); 
      config.ObjectSchema = ".dbo"; 

      if (!config.ScopeExists(provider.ScopeName)) 
      { 

       DbSyncScopeDescription scopeDesc = SqlSyncDescriptionBuilder.GetDescriptionForScope(provider.ScopeName, sourceConnection); 
       config.PopulateFromScopeDescription(scopeDesc); 
       config.Apply(); 

      } 

     } 

     private static void deprovisionServerClient(SqlSyncProvider provider) 
     { 
      SqlSyncScopeDeprovisioning serverSqlDepro = new SqlSyncScopeDeprovisioning((SqlConnection)provider.Connection); 
      serverSqlDepro.DeprovisionScope(provider.ScopeName); 
      serverSqlDepro.DeprovisionStore(); 
     } 

    } 
} 

最後感謝大家對你提供的幫助。

相關問題