Monday, March 7, 2011

Debugging Sync Framework / DbApplyChangeFailedEventArgs

hi,

 
Lastly I was busy working in sync, basically sync between on-premise sql server and Azure server. for this I created -

 
after good amount of testing and all, I started getting error in sync, and was completely unable to get details about the error.
Liam code does not provide details about the error, just the boolean flag, whether done or not. same with CTP2, and I need to know the details about error.
Thanks to http://softarchitect.wordpress.com/2010/10/03/software-architecture-sync-data-between-offline-disconnected-databases-sync-framework/ I was able to get the exact Error and then little googling around 'DbApplyChangeFailedEventArgs. http://msdn.microsoft.com/en-us/library/microsoft.synchronization.data.dbapplychangefailedeventargs.aspx
helped me crack the error.
So finally the code which worked out for debugging is


public static void Sync(System.IO.StreamWriter file)


{

SqlConnection sqlServerConn = new SqlConnection(sqllocalConnectionString);

SqlConnection sqlAzureConn = new SqlConnection(sqlazureConnectionString);

try

{

SyncOrchestrator orch = new SyncOrchestrator

{

LocalProvider = new SqlSyncProvider(scopeName, sqlAzureConn),

RemoteProvider = new SqlSyncProvider(scopeName, sqlServerConn),

Direction = SyncDirectionOrder.UploadAndDownload



};

((SqlSyncProvider)orch.LocalProvider).ApplyChangeFailed += new EventHandler(Program_ApplyChangeFailed);

file.WriteLine("Starting Sync:: " + DateTime.Now);


}



catch (Exception ex)

{

file.WriteLine("Error in SYNC:" + ex.Message);

file.WriteLine("Error in Sync stack trace Message:" + ex.StackTrace);

}



finally

{

sqlAzureConn.Close();

sqlServerConn.Close();

}



}





static void Program_ApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)



{



// display conflict type







// display error message

Console.WriteLine(e.Conflict.Type);

DataTable conflictingRemoteChange = e.Conflict.RemoteChange;

DataTable conflictingLocalChange = e.Conflict.LocalChange;

int remoteColumnCount = conflictingRemoteChange.Columns.Count;

Console.WriteLine(String.Empty);

Console.WriteLine(String.Empty);

Console.WriteLine(String.Empty);

Console.Write("
");



//Display the remote row from _tracking table.

for (int i = 0; i < remoteColumnCount; i++)

{

Console.Write(conflictingRemoteChange.Rows[0][i] + "
");

}



//Ask for a conflict resolution option.

Console.WriteLine(String.Empty);

Console.WriteLine(String.Empty);

Console.WriteLine("Enter a resolution option for this conflict:");

string conflictResolution = Console.ReadLine();

conflictResolution.ToUpper();



if (conflictResolution == "A")

{

e.Action = ApplyAction.Continue;

}



else if (conflictResolution == "B")

{

e.Action = ApplyAction.RetryWithForceWrite;

}



else

{

Console.WriteLine(String.Empty);

Console.WriteLine("Not a valid resolution option.");

}





Console.WriteLine(e.Error);



}