【问题标题】:how can i synchronize different column's name in 2 differents database tables? [closed]如何在 2 个不同的数据库表中同步不同的列名? [关闭]
【发布时间】:2014-05-25 06:03:18
【问题描述】:

您好,我想同步 2 个不同的数据库、表和列。我创建了 SYNC 应用程序。通过使用同步框架。它由 azure 托管。我也读过以下文章:

http://jtabadero.wordpress.com/2011/08/19/part-4-synchronizing-tables-with-different-table-names-and-column-names/ http://www.devart.com/dotconnect/oracle/docs/SyncFramework.html
但我有一个 Nullreference 异常。 OrderTable 没有正确的列。看图片。如何解决这个问题。

namespace WorkerRole1
{
    public class WorkerRole : RoleEntryPoint
    {
        public override void Run()
        {
            // This is a sample worker implementation. Replace with your logic.
            Trace.TraceInformation("WorkerRole1 entry point called", "Information");
            Setup();
            while (true)
            {
                Sync();
                Thread.Sleep(10000);
                Trace.TraceInformation("Working", "Information");
            }
        }

    private void Setup()
    {

        string scopeName = "DifferentSchemaScope";
        string MemberSQLAzureConnectionString = ConfigurationManager.ConnectionStrings["MemberSQLAzureConnectionString"].ConnectionString;
        string HubSQLAzureConnectionString = ConfigurationManager.ConnectionStrings["HubSQLAzureConnectionString"].ConnectionString;
        using (SqlConnection sqlMemberAzureConn = new SqlConnection(MemberSQLAzureConnectionString))
        {

            using (SqlConnection sqlHubAzureConn = new SqlConnection(HubSQLAzureConnectionString))
            {


                if (sqlHubAzureConn.State == System.Data.ConnectionState.Open && sqlMemberAzureConn.State == ConnectionState.Open)
                {


                    DbSyncScopeDescription myScope = new DbSyncScopeDescription(scopeName);

                    DbSyncTableDescription serverTableDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable("myTest.SourceOrderTable", sqlHubAzureConn);
                    serverTableDesc.GlobalName = "OrderTable";

                    DbSyncTableDescription clientTableDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable("myTest.DestinationOrderTable", sqlMemberAzureConn);


                    clientTableDesc.GlobalName = "OrderTable";

                    myScope.Tables.Add(serverTableDesc);
                    myScope.Tables.Add(clientTableDesc);




                    SqlSyncScopeProvisioning sqlServerProv = new SqlSyncScopeProvisioning(myScope);
                    SqlSyncScopeProvisioning sqlAzureProv = new SqlSyncScopeProvisioning(myScope);

                    sqlServerProv.PopulateFromScopeDescription(myScope);




                    myScope.Tables["OrderTable"].Columns.Remove(myScope.Tables["OrderTable"].Columns["OrderQty"]);
                    myScope.Tables["OrderTable"].Columns["OrderId"].IsPrimaryKey = true;
                    sqlAzureProv.PopulateFromScopeDescription(myScope);



                    if (!sqlServerProv.ScopeExists(scopeName, sqlHubAzureConn))
                    {

                        sqlServerProv.Apply(sqlHubAzureConn);

                    }

                    // sqlAzureProv.SetCreateTableDefault(DbSyncCreationOption.Skip);

                    if (!sqlAzureProv.ScopeExists(scopeName, sqlMemberAzureConn))
                    {

                        sqlAzureProv.Apply(sqlMemberAzureConn);
                    }
                }
            }
        }
    }


    private void Sync()
    {

        string scopeName = "DifferentSchemaScope";
        string MemberSQLAzureConnectionString = ConfigurationManager.ConnectionStrings["MemberSQLAzureConnectionString"].ConnectionString; //CloudConfigurationManager.GetSetting("MemberSQLAzureConnectionString");
        string HubSQLAzureConnectionString = ConfigurationManager.ConnectionStrings["HubSQLAzureConnectionString"].ConnectionString;  //CloudConfigurationManager.GetSetting("HubSQLAzureConnectionString");
        using (SqlConnection sqlMemberAzureConn = new SqlConnection(MemberSQLAzureConnectionString))
        {

            using (SqlConnection sqlHubAzureConn = new SqlConnection(HubSQLAzureConnectionString))
            {

                var localProvider = new SqlSyncProvider(scopeName, sqlHubAzureConn);
                var remoteProvider = new SqlSyncProvider(scopeName, sqlMemberAzureConn);

                remoteProvider.ChangesSelected += remoteProvider_ChangesSelected;

                SyncOrchestrator syncOrchestrator = new SyncOrchestrator
                {
                    LocalProvider = localProvider,
                    RemoteProvider = remoteProvider,
                    Direction = SyncDirectionOrder.UploadAndDownload
                };

                syncOrchestrator.Synchronize();
            }
        }
    }



    void remoteProvider_ChangesSelected(object sender, DbChangesSelectedEventArgs e)
    {
        if (e.Context.DataSet.Tables.Contains("OrderTable"))
        {
            DataTable dataTable = new DataTable();
            dataTable = e.Context.DataSet.Tables["OrderTable"];

            //rename the columns to match the destination table’s column names
            dataTable.Columns["OrderId"].ColumnName = "OrderNo";
            dataTable.Columns["OrderDesc"].ColumnName = "OrderDetail";

        }
    }

    public override bool OnStart()
    {
        // Set the maximum number of concurrent connections 
        ServicePointManager.DefaultConnectionLimit = 12;

        // For information on handling configuration changes
        // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.

        return base.OnStart();
    }
}

}

SQL:

id 应该是主键......

创建模式 myTest

创建表 [myTest].[SourceOrderTable]( [OrderId] [int] IDENTITY(1,1) 非空, [OrderDesc] nvarchar NULL)

CREATE TABLE [myTest].[DestinationOrderTable](
[OrderNo] [int] IDENTITY(1,1) NOT NULL,
[OrderDetail] [nvarchar](50) NULL,
[OrderQty] int NULL)

但它不起作用。它在“void remoteProvider_ChangesSelected(object sender, DbChangesSelectedEventArgs e)”上产生了一个错误,这就是为什么 remoteprovider 列名没有改变。remoteProvider 列名是“OrderNo,OrderDetail”,但它必须是“OrderId,OrderDesc”看图片:

错误图片:

【问题讨论】:

  • 每一个 NullReferenceException 问题都可能重复
  • 你误解了我的问题。我有足够的信息来解决这个问题。 RemoteProvider 表不包含 orderid,orderdesc.WHY?你看到我的代码和文章了吗?
  • 我读了你的代码。您无缘无故地创建了一个dataTable,因为您将它分配给了下一行的其他内容。
  • 好的。如何在 2 个不同的数据库表中同步不同列的名称?
  • 你能发布本地和远程表结构吗?

标签: c# azure azure-sql-database azure-storage microsoft-sync-framework


【解决方案1】:

检查您的同步方向。 它说上传和下载,您将 ChangesSelected 绑定到作为您的目的地的远程提供程序上。

该事件将在下载时触发​​,您的“目的地”现在是您的来源。所以你数据集中的内容是有效的,这就是目标表中选择更改的结构(现在是源,因为下载时同步方向是相反的)

由于您正在进行双向同步,因此您应该在两个提供程序上都有 ChangesSelected 事件。

本地提供者 ChangesSelected 应该映射 OrderId -> OrderNo / OrderDesc->OrderDetail

远程提供者 ChangesSelected 应该是相反的 OrderNo -> OrderId / OrderDetail->OrderDesc

【讨论】:

  • 我只想在远程上进行更改。 OrderNo -> OrderId / OrderDetail->OrderDesc 不正确。你能给我一点样品吗?这对我来说真的很重要......
  • 我建议你暂停一下,想想你想要什么。你上面得到的错误是正确的。您正在尝试在远程表中查找本地列。当然,它不存在。你只是想上传吗?然后将同步方向设置为上传并按照我上面的建议进行本地提供程序更改。上面的整个逻辑是在选择更改后重命名列,使其与目标匹配。
  • 我做到了。但它不工作。我只想更新目的地。但我需要一个映射...
  • 什么不起作用?上面的代码和您使用的代码正是如何进行映射。
  • 同步不工作....
猜你喜欢
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-10
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多