Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I am trying to set up synchronization between two SQL Compact 3.5 databases using SqlCeSyncProvider. I am able to create a scope for the two databases, which creates a meta table. When I try to run SyncOrchestrator.Synchronize() though, I get the following error and am not able to get the two databases to synchronize when I insert data:

"An error occurred when initializing adapters for scope 'Person'. Ensure that the scope name specified on the provider exists in the scope metadata table, and that the correct base tables are specified for that scope."

When I run the following code, three tables are created for each database: Sync_Person_tracking, Sync_scope_config, and Sync_scope_info. Both databases contain the same scope name of Person in the Sync_scope_info table.

    SqlCeSyncScopeProvisioning ceConfig = new SqlCeSyncScopeProvisioning();
    SqlCeConnection ceConn = (SqlCeConnection)syncProvider.Connection;
    string scopeName = syncProvider.ScopeName;
    if (!ceConfig.ScopeExists(scopeName, ceConn)) {
        var description = new DbSyncScopeDescription();
        description.ScopeName = scopeName;
        var table = new DbSyncTableDescription("Person");
        var pkCol = new DbSyncColumnDescription("ID", "int");
        pkCol.IsPrimaryKey = true;
        table.Columns.Add(pkCol);
        table.Columns.Add(new DbSyncColumnDescription("Name", "nvarchar 50"));
        table.Columns.Add(new DbSyncColumnDescription("Height", "int"));
        table.Columns.Add(new DbSyncColumnDescription("Weight", "int"));
        description.Tables.Add(table);
        ceConfig.PopulateFromScopeDescription(description);
        ceConfig.SetCreateTableDefault(DbSyncCreationOption.Skip);
        ceConfig.ObjectPrefix = "Sync";
        ceConfig.Apply(ceConn);
    }

In the above code, syncProvider is a SqlCESyncProvider object with a connection string attached to the specified database.

Here is the code I use to set up synchronization between the databases using SyncOrchestrator:

    _syncOrchestrator.LocalProvider = localSyncProvider;
    _syncOrchestrator.RemoteProvider = remoteSyncProvider;
    _syncOrchestrator.Direction = SyncDirectionOrder.DownloadAndUpload;

    try {
        var sync = _syncOrchestrator.Synchronize();
        Console.WriteLine(string.Format("Sync Downloads: {0}\nSync Uploads: {1}\nSync Start Time: {2}\nSync End Time: {3}",
            sync.DownloadChangesTotal.ToString(), sync.UploadChangesTotal.ToString(),
            sync.SyncStartTime, sync.SyncEndTime));
    } catch (Exception ex) {
        Console.WriteLine(string.Format("Sync Orchestrator threw exception: {0}", ex.Message));
    }

Thanks in advance for any help!

share|improve this question

1 Answer 1

up vote 0 down vote accepted

I was able to solve the error by changing the provisioning. Instead of calling the above code for each of the two databases, I created a single function as shown below:

    public void SetupScope() {
        if (ProvidersCollection["Local"] != null && ProvidersCollection["Remote"] != null) {
            var localConnection = (SqlCeConnection)((SqlCeSyncProvider)ProvidersCollection["Local"]).Connection;
            var remoteConnection = (SqlCeConnection)((SqlCeSyncProvider)ProvidersCollection["Remote"]).Connection;

            var localScopeDescription = new DbSyncScopeDescription("LocalPerson");
            var localPersonTableDescription = SqlCeSyncDescriptionBuilder.GetDescriptionForTable("Person", remoteConnection);
            localScopeDescription.Tables.Add(localPersonTableDescription);

            var localDatabaseConfiguration = new SqlCeSyncScopeProvisioning(localConnection);
            try {
                localDatabaseConfiguration.PopulateFromScopeDescription(localScopeDescription);
                localDatabaseConfiguration.ObjectPrefix = "Sync";
                localDatabaseConfiguration.SetCreateTableDefault(DbSyncCreationOption.CreateOrUseExisting);
                localDatabaseConfiguration.Apply();
            } catch (Exception ex) {
                Console.WriteLine(string.Format("{0}", ex.Message));
            }

            var remoteScopeDescription = new DbSyncScopeDescription("RemotePerson");
            var remotePersonTableDescription = SqlCeSyncDescriptionBuilder.GetDescriptionForTable("Person", localConnection);
            remoteScopeDescription.Tables.Add(remotePersonTableDescription);

            var remoteDatabaseConfiguration = new SqlCeSyncScopeProvisioning(remoteConnection);
            try {
                remoteDatabaseConfiguration.PopulateFromScopeDescription(remoteScopeDescription);
                remoteDatabaseConfiguration.ObjectPrefix = "Sync";
                remoteDatabaseConfiguration.SetCreateTableDefault(DbSyncCreationOption.CreateOrUseExisting);
                remoteDatabaseConfiguration.Apply();
            } catch (Exception ex) {
                Console.WriteLine(string.Format("{0}", ex.Message));
            }
        }
    }

The difference here is that for each of the two databases, I now reference the connection of the other database when setting up my table descriptions.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.