【发布时间】: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