【问题标题】:Microsoft Sync Framework ErrorMicrosoft 同步框架错误
【发布时间】:2014-02-06 19:37:21
【问题描述】:

我正在使用 Microsoft Sync Framework v2.1 来同步两个数据库,即从远程(ms sql server 2012)到本地(ms sql server express 2008 R2)。可以在本地数据库上成功创建表,但是由于以下错误导致数据未同步:

当前操作无法完成,因为数据库未配置为同步,或者您没有同步配置表的权限。

但是,在同步2个本地数据库时(使用ms sql server express 2008 R2),同步成功。

有人对可能出现的问题有什么建议吗?

谢谢。

代码

以下是主要形式:

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // create a connection to the SyncExpressDB database
            string clientConn = ConfigurationManager.ConnectionStrings["ianConnection"].ConnectionString;

            // create a connection to the SyncDB server database
            string serverConn = ConfigurationManager.ConnectionStrings["arvixeConnection"].ConnectionString;

            Utilities.Synchronisation.Db.DBSynchroniser dbSync = new DBSynchroniser(clientConn, serverConn);
            dbSync.ProvisionSyncScope("TestScope", "Products", DBSyncSide.Both);
            dbSync.Sync(Microsoft.Synchronization.SyncDirectionOrder.Download, "TestScope");
            label1.Text = "Sync Done !!!";
        }
    }

以下是同步类

public class DBSynchroniser
    {
        SqlConnection clientConnection;
        SqlConnection serverConnection;

        SyncOrchestrator syncOrchestrator;

        private EventHandler<DbApplyChangeFailedEventArgs> changeFailedHandler;
        public EventHandler<DbApplyChangeFailedEventArgs> ChangeFailedHandler
        {
            get { return changeFailedHandler; }
            set { changeFailedHandler = value; }
        }

        public DBSynchroniser(string clientConn, string serverConn)
        {
            clientConnection = new SqlConnection(clientConn);
            serverConnection = new SqlConnection(serverConn);

            syncOrchestrator = new SyncOrchestrator();
            changeFailedHandler = new EventHandler<DbApplyChangeFailedEventArgs>(ApplyChangeFailed);
        }

        public void ProvisionSyncScope(string syncScopeName, string tableName, DBSyncSide syncSide)
        {
            ProvisionSyncScope(syncScopeName, new List<string>(new string[] { tableName }), syncSide);
        }


        public void ProvisionSyncScope(string syncScopeName, List<string> tableNames, DBSyncSide syncSide)
        {

            DbSyncScopeDescription scopeDesc;
            // define a new scope
            scopeDesc = new DbSyncScopeDescription(syncScopeName);
            scopeDesc.UserComment = "This is to test the sync class";

            foreach (string name in tableNames)
            {
                // get the description of the table name
                // and add the table description to the sync scope definition
                scopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable(name, serverConnection));
            }

            // create a server scope provisioning object based on the ProductScope
            SqlSyncScopeProvisioning serverProvision = new SqlSyncScopeProvisioning(serverConnection, scopeDesc);
            SqlSyncScopeProvisioning clientProvision = new SqlSyncScopeProvisioning(clientConnection, scopeDesc);

            // skipping the creation of table since table already exists on server
            serverProvision.SetCreateTableDefault(DbSyncCreationOption.CreateOrUseExisting);
            clientProvision.SetCreateTableDefault(DbSyncCreationOption.CreateOrUseExisting);

            // start the provisioning process
            switch (syncSide)
            {
                case DBSyncSide.Client:
                    clientProvision.Apply();
                    break;
                case DBSyncSide.Server:
                    serverProvision.Apply();
                    break;
                case DBSyncSide.Both:
                    serverProvision.Apply();
                    clientProvision.Apply();
                    break;
                default:
                    break;
            }

        }

        public void DeprovisionScope(string scopeName, DBSyncSide syncSide)
        {
            SqlSyncScopeDeprovisioning clientSqlDepro = new SqlSyncScopeDeprovisioning(clientConnection);
            SqlSyncScopeDeprovisioning serverSqlDepro = new SqlSyncScopeDeprovisioning(serverConnection);

            // First save the deprovisioning script so it can be run on other SQL Server client databases.
            // This step is optional.
            //File.WriteAllText("SampleDeprovisionScript.txt", clientSqlDepro.ScriptDeprovisionScope(scopeName));

            // Remove the scope.
            switch (syncSide)
            {
                case DBSyncSide.Client:
                    clientSqlDepro.DeprovisionScope(scopeName);
                    break;
                case DBSyncSide.Server:
                    serverSqlDepro.DeprovisionScope(scopeName);
                    break;
                case DBSyncSide.Both:
                    clientSqlDepro.DeprovisionScope(scopeName);
                    serverSqlDepro.DeprovisionScope(scopeName);
                    break;
                default:
                    break;
            }

        }

        public DBSyncOperationStatistics Sync(SyncDirectionOrder direction, string syncScopeName)
        {
            // set local provider of orchestrator to a sync provider associated with the 
            // MySyncScope in the client database
            syncOrchestrator.LocalProvider = new SqlSyncProvider(syncScopeName, clientConnection); //check objectPrefix and schema

            // set the remote provider of orchestrator to a server sync provider associated with
            // the MySyncScope in the server database
            syncOrchestrator.RemoteProvider = new SqlSyncProvider(syncScopeName, serverConnection); //check objectPrefix and schema

            // set the direction of sync session to Upload and Download
            syncOrchestrator.Direction = direction;

            // subscribe for errors that occur when applying changes to the client
            ((SqlSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed += changeFailedHandler;

            // execute the synchronization process
            DBSyncOperationStatistics syncStats = new DBSyncOperationStatistics(syncOrchestrator.Synchronize());

            //return statistics of synchronisation
            return syncStats;
        }



        private void ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)
        {
            throw e.Error;
        }


        ~DBSynchroniser()
        {
            if (clientConnection.State == System.Data.ConnectionState.Open)
            {
                clientConnection.Close();
                clientConnection.Dispose();
            }

            if (serverConnection.State == System.Data.ConnectionState.Open)
            {
                serverConnection.Close();
                serverConnection.Dispose();
            }
        }
    }

【问题讨论】:

  • 您是否在服务器上配置数据库?我通常在将数据移动到服务器后执行 PerformPostRestoreFixup,然后在服务器上配置数据库。
  • 您使用的是非 dbo 架构吗?
  • 我不是数据库专家,但我认为我使用的是 dbo 模式,因为在每个表名前面都有 dbo(例如:dbo.Users、dbo.Towns) .关于 PeterJ 的问题,我认为我正在配置,因为在两个数据库中都创建了所有必需的字段,例如 schema.info、tableName.tracking 等。但是,我无法将数据从远程数据库传输到本地数据库。在下一条评论中,我将发布用于同步的代码
  • 我已经编辑了帖子本身,我添加了用于同步的代码。问题可能是未指定的 ObjectPrefix 和架构吗?我在我的代码中做了评论,但我不知道什么是 ObjectPrefix 请参阅我帖子中的 CODE 部分。谢谢。
  • 在 scope_info 表中,您在其中看到您的范围名称吗?同样,为什么每次同步时都要进行配置?您应该只配置一次范围。

标签: sql sql-server database synchronization microsoft-sync-framework


【解决方案1】:

我已经解决了这个问题。正如我所想,这是一个与模式相关的问题。我指定了正确的模式,因为远程数据库上的模式与本地模式不同,问题就解决了。感谢您的所有帮助。

【讨论】:

  • 你能把代码分享给我吗,因为我想让同步框架工作但不知道该怎么做
【解决方案2】:

我有同样的问题 正如尊敬的 user3206587 提到的那样

Clientserver 架构必须相似,例如它们都应该是 dbo

因为如果表前缀变得不同,我们将面临例如配置或权限错误

dbo.tblTestsampleUser.tblTest

不同

您应该更改服务器上示例用户的默认架构 与您的本地数据库完全相同。

我在这里演示了如何做这些事情:

【讨论】:

    猜你喜欢
    • 2013-01-09
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    相关资源
    最近更新 更多