locked
SyncFX 2.1 - set to bi-directional but not downloading RRS feed

  • Question

  • I'm using Sync Framework 2.1 to synchronise between a SQL Server 2005 database and several SQL Compact SP2 (desktop) databases.

    Everything works fine for a single SQL Server Compact client synching to the server. But when I try to sync 2 SQL Server Compact clients to the same server database, changes I make to the 1st client are not synchronised to the 2nd client. I know the changes have gone to the server database because I can see them. I can't understand why this is happening.

    Here's a copy of my code:

        public class DataSynching

        {

            private const string SyncScopeName = "DataSynchronisation";

     

            SqlConnection serverConn = null;

            SqlCeConnection clientConn = null;

     

            public DataSynching()

            {

                ScopeAndProvisionSqlServer();

                ScopeAndProvisionSqlCompact();

            }

     

            private void ScopeAndProvisionSqlServer()

            {

                serverConn = new SqlConnection(LocalSettings.GetSetting(LocalSettings.SettingsKey.DatabaseConnectionString));

     

                DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription(SyncScopeName);

     

                DbSyncTableDescription tableDescAddress = SqlSyncDescriptionBuilder.GetDescriptionForTable("Address", serverConn);

                DbSyncTableDescription tableDescBranch = SqlSyncDescriptionBuilder.GetDescriptionForTable("Branch", serverConn);

                DbSyncTableDescription tableDescUser = SqlSyncDescriptionBuilder.GetDescriptionForTable("User", serverConn);

                DbSyncTableDescription tableDescItem = SqlSyncDescriptionBuilder.GetDescriptionForTable("Item", serverConn);

                DbSyncTableDescription tableDescJob = SqlSyncDescriptionBuilder.GetDescriptionForTable("Job", serverConn);

                DbSyncTableDescription tableDescSite = SqlSyncDescriptionBuilder.GetDescriptionForTable("Site", serverConn);

     

                scopeDesc.Tables.Add(tableDescAddress);

                scopeDesc.Tables.Add(tableDescBranch);

                scopeDesc.Tables.Add(tableDescUser);

                scopeDesc.Tables.Add(tableDescItem);

                scopeDesc.Tables.Add(tableDescJob);

                scopeDesc.Tables.Add(tableDescSite);

     

                SqlSyncScopeProvisioning serverProvision = new SqlSyncScopeProvisioning(serverConn, scopeDesc);

     

                serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);

     

                serverProvision.Tables["Item"].AddFilterColumn("customer_id");

                serverProvision.Tables["Item"].FilterClause = String.Format("[customer_id] = {0}", Proxy.GetSQLValue(Customer.SelectedCustomer.ID));

     

     

                if (!serverProvision.ScopeExists(SyncScopeName))

                {

                    serverProvision.Apply();

                }

            }

     

            private void ScopeAndProvisionSqlCompact()

            {

                clientConn = new SqlCeConnection(Customer.SelectedCustomer.ConnectionString);

     

                DbSyncScopeDescription scopeDesc = SqlSyncDescriptionBuilder.GetDescriptionForScope(SyncScopeName, serverConn);

     

                SqlCeSyncScopeProvisioning clientProvision = new SqlCeSyncScopeProvisioning(clientConn, scopeDesc);

     

                clientProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);

     

                clientProvision.Apply();

            }

     

            public SyncOperationStatistics SyncData()

            {

                SyncOrchestrator syncOrchestrator = new SyncOrchestrator();

     

                clientConn = new SqlCeConnection(Customer.SelectedCustomer.ConnectionString);

     

                syncOrchestrator.LocalProvider = new SqlCeSyncProvider(SyncScopeName, clientConn);

     

                syncOrchestrator.RemoteProvider = new SqlSyncProvider(SyncScopeName, serverConn);

     

                syncOrchestrator.Direction = SyncDirectionOrder.UploadAndDownload;

     

                ((SqlCeSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(DataSync_LocalApplyChangeFailed);

                ((SqlSyncProvider)syncOrchestrator.RemoteProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(DataSync_RemoteApplyChangeFailed);

               

     

                return syncOrchestrator.Synchronize();

            }

     

            void DataSync_LocalApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)

            {

                if (e.Error != null)

                {

                    e.Error.ToString();

                }

            }

     

            void DataSync_RemoteApplyChangeFailed(object sender, DbApplyChangeFailedEventArgs e)

            {

                if (e.Error != null)

                {

                    e.Error.ToString();

                }

            }

     Can someone please help?

     

    • Edited by Abs A Tuesday, December 21, 2010 4:20 PM
    Monday, December 20, 2010 3:40 PM

Answers

  • Hi Jin.

    I've added ChangesApplied event handlers for both the local and remote provider and set up tracing but couldn't find the problem that way.

    I took a step back and looked at synching a really simple database with only 2 tables. After further investigation, I found that the problem was due to a non-provisioned compact database being synchronised with a previously provisioned SQL Server database. This happened because I added the compact database to my Visual Studio solution and set it to be copied to the application's folder.

    After I removed the changes caused by Sync Framework provisioning the SQL Server database and re-synchronised the issue was resolved.

    Thanks for your prompt help Jin, it's greatly appreciated.

    Abrar.

    Thursday, December 30, 2010 11:02 AM

All replies

  • On the second compact db client, have you see the ApplyChangeFailed event fire? (maybe change e.Error.ToString() to console.WriteLine( e.Error.ToString());)

    If you update on a server row, will that sync to the second compact db client?

    The above check will help to investigate whether the sync is set up correctly between the server and second compact db and whether there are failures during the sync.

    Monday, December 20, 2010 6:08 PM
    Answerer
  • Hi Jin,

    Thanks for the reply.

    The ApplyChangeEvent does not fire for either the sql server db or the compact db. Also, when I get the SyncOperationStatistics object back from SyncData(), I don't get any failures for either uploads or downloads. The values for DownloadChangesApplied, DownloadChangesFailed, DownloadChangesTotal, UploadChangesTotal, UploadChangesApplied, UploadChangesFailed are all zero so it seems as if the Sync Framework has tried syncing but there's nothing to sync.

    Yes, if I update the server row and sync either client, their value gets updated.

    One interesting thing I've noticed:
    When I update a single record on the server and sync to either client, the value of DownloadChangesApplied and DownloadChangesTotal are both 1. That's expected. But if I change a single record on the client, the value of UploadChangesTotal and UploadChangesApplied are 2.

    Thanks again for your help.

    Abrar.

    Tuesday, December 21, 2010 9:30 AM
  • For the uploadChanges to 2 issue, you could use a ChangesApplied event handler to see what changes are applied, to rule out the possibilities of a previous change not synced yet or some custom logic on either side.

    For the original problem, you could use event handler for SelectingChanges on server, ChangesApplied, ApplyChangesFailed on client to see whether the client 1's change is enumerated on the server.

    If above efforts can not discover a problem, you may need to turn on database sync tracing to investigate. basically if you insert a row with PK  1234 on client 1, turning on tracing, sync it to server, see that in the trace, pk 1234 is inserted on the server, then sync it to the client 2 and see whether 1234 is picked up as changes and whether it's applied to client 2. To enable sync tracing, check http://msdn.microsoft.com/en-us/library/cc807160.aspx.

    Tuesday, December 21, 2010 6:45 PM
    Answerer
  • Hi Jin.

    I've added ChangesApplied event handlers for both the local and remote provider and set up tracing but couldn't find the problem that way.

    I took a step back and looked at synching a really simple database with only 2 tables. After further investigation, I found that the problem was due to a non-provisioned compact database being synchronised with a previously provisioned SQL Server database. This happened because I added the compact database to my Visual Studio solution and set it to be copied to the application's folder.

    After I removed the changes caused by Sync Framework provisioning the SQL Server database and re-synchronised the issue was resolved.

    Thanks for your prompt help Jin, it's greatly appreciated.

    Abrar.

    Thursday, December 30, 2010 11:02 AM