问题
Hi i would like to sync 2 different database and tables and columns.i created SYNC app. by using a sync framework.it is hosted by azure. also i've read below articles:
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
But i have a Nullreference exception. OrderTable havent got correct columns. Look pics. How to solve this problem.
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 should be primary key....
CREATE SCHEMA myTest
CREATE TABLE [myTest].[SourceOrderTable]( [OrderId] [int] IDENTITY(1,1) NOT NULL, [OrderDesc] nvarchar NULL)
CREATE TABLE [myTest].[DestinationOrderTable](
[OrderNo] [int] IDENTITY(1,1) NOT NULL,
[OrderDetail] [nvarchar](50) NULL,
[OrderQty] int NULL)
but it is not working. it produced an error on "void remoteProvider_ChangesSelected(object sender, DbChangesSelectedEventArgs e)" That's Why remoteprovider columns name is not changed.remoteProvider Columns Names are "OrderNo,OrderDetail" but it must be "OrderId ,OrderDesc" look picture:
ERROR picture:
回答1:
check your sync direction. it says Upload and Download, you bind the ChangesSelected on the remote provider which is your destination.
the event will fire on the download, your "destination" is now your source. so whats in you dataset is valid, thats the structure in the destination table where the changes were selected (which is now the source because the sync direction is reversed on download)
since you are doing bidirectional sync, you should have ChangesSelected event on both providers.
the local provider ChangesSelected should map OrderId -> OrderNo / OrderDesc->OrderDetail
the remote provider ChangesSelected should be the opposite OrderNo -> OrderId / OrderDetail->OrderDesc
来源:https://stackoverflow.com/questions/23006547/how-can-i-synchronize-different-columns-name-in-2-differents-database-tables