2014-04-30 52 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(); 
     } 

    } 
} 

最后感谢大家对你提供的帮助。

相关问题