I am trying to create a windows application using vs 2010 in c# which will sync two database where one database is on local machine and another on server. Here is my sample code.
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();
}
}
}
}
When i used this same code on two database running both on same machine it worked perfectly. But when i used plesk panel server database its getting an error saying your database is not provisioned. When I opened the server database I saw the tables have been created but there are no data. Another thing is that whenever i tried to see the table data it says “index out of bound array [Microsoft.SqlServer.Smo]”.
Please Suggest what to do. Thanks in advance
3
Answers
In this small projects I faced couple of problems.
Problem 1:
SOLUTION:
Problem 2 & Problem 3
SOLUTION
config.ObjectSchema = ".dbo";
And now it works perfectly. Here is the complete working code...
Finally thank you everyone for the help you have provided.
There are multiple workarounds with some limitations as mentioned below…
Install Microsoft® SQL Server® 2012 Express – you can download it from here http://www.microsoft.com/en-us/download/details.aspx?id=29062. The only limitation is supported operating systems: Windows 7, Windows Server 2008 R2, Windows Server 2008 Service Pack 2, Windows Vista Service Pack 2.
If you have SQL Server 2008 or 2008 R2 install you may choose for this fix –http://support.microsoft.com/kb/2459027
chances are your Sync Fx objects are being created in non-dbo schema.
you can force them to use the same schema during provisioning and during synchronization by setting the ObjectSchema property.
in your code above:
during provisioning set config.ObjectSchema=”dbo”; or whatever schema you want to use.
during sync, set provider1.ObjectSchema=”dbo”; or whatever schema you want to use.
the key thing is that whatever schema you used in the provisioning should be the same during synchronization.
if you dont dont want to deprovision, set the ObjectSchema=”userx” (or whatever schema the objects were created) on the sync provider pointing to your plesk panel database