none
How to modify a scope under the Sync Framework 2.0 CTP2 RRS feed

  • Question

  • Hi,

    I am trying the new Sync Framework 2.0CTP2 with the database collaboration codes. I would like to know if I can change the scope after provisioning.

    Let's say I had already provisioned table A and C in a databse with a scope S. The system had added two tracking objects A_tracking and C_tracking in the databse. Later on, I want to add a table D in the scope S. Is it possible to modify the scope to include table D? I tried to apply the scope again with the new table D but I encountered error as the database had objects A_tracking and C_tracking created before. What's the proper way to modify a scope?

    Thanks for your help. 
    Friday, June 12, 2009 5:41 AM

Answers

  • Once a scope has been configured and synchronizing, there is currently not a way to push the incremental schema changes to the clients.  This will have to be coordinated by the developer.

    When creating scopes using tables that have already been provisioned, the provisioning objects allow you to specify what gets created for what table.  On the SqlSyncScopeProvisioning object, you can set the default action to be Skip for creating tracking tables, etc.  This will specify that all tables in that scope should not create provisioning objects.  Then for the SqlSyncTableProvisioning object for table D, you can re-enable the creation.

    DbSyncScopeDescription scopeDesc; // Set this up as needed, adding A, C, and D
    SqlSyncScopeProvisioning scopeProv = new SqlSyncScopeProvisioning(scopeDesc);
    
    // Set the default action to be "Skip" for all tables
    scopeProv.SetCreateTableDefault(DbSyncCreationOption.Skip);
    // There are a series of these "SetCreate*Default" options.  Set them accordingly.
    
    // Set the action to be "Create" for the SqlSyncTableProvisioning object for table D
    scopeProv["D"].CreateTable = DbSyncCreationOption.Create;
    // Again, there are other "Create*" properties.
    You can also use the .Script() function on SqlSyncScopeProvisioning to generate a SQL script that will do the provisioning and you can tweak that by hand to eliminate the unnecessary CREATE statements.

    Hope this helps.
    Thanks-
    Friday, June 19, 2009 4:43 PM
    Answerer

All replies

  • Once a scope has been configured and synchronizing, there is currently not a way to push the incremental schema changes to the clients.  This will have to be coordinated by the developer.

    When creating scopes using tables that have already been provisioned, the provisioning objects allow you to specify what gets created for what table.  On the SqlSyncScopeProvisioning object, you can set the default action to be Skip for creating tracking tables, etc.  This will specify that all tables in that scope should not create provisioning objects.  Then for the SqlSyncTableProvisioning object for table D, you can re-enable the creation.

    DbSyncScopeDescription scopeDesc; // Set this up as needed, adding A, C, and D
    SqlSyncScopeProvisioning scopeProv = new SqlSyncScopeProvisioning(scopeDesc);
    
    // Set the default action to be "Skip" for all tables
    scopeProv.SetCreateTableDefault(DbSyncCreationOption.Skip);
    // There are a series of these "SetCreate*Default" options.  Set them accordingly.
    
    // Set the action to be "Create" for the SqlSyncTableProvisioning object for table D
    scopeProv["D"].CreateTable = DbSyncCreationOption.Create;
    // Again, there are other "Create*" properties.
    You can also use the .Script() function on SqlSyncScopeProvisioning to generate a SQL script that will do the provisioning and you can tweak that by hand to eliminate the unnecessary CREATE statements.

    Hope this helps.
    Thanks-
    Friday, June 19, 2009 4:43 PM
    Answerer
  • Hi Phil,

    It is very helpful. I spent a number of days in devising this manually.But the approach you suggested really is quick. Thanks !!

    I have another query: I can set the CreationOption as Create for the very first run. But subsequently I need to change it back to Skip. 
     
    For server it has to be handled the very first run by any user and on respective clients, it needs to be handled after first run by that client.
    Also when I recreate my client/server I need to handle this again.

    Is there any way like CreateIfDoesNotExist or any way to handle this in SqlSyncProvider. I think for SqlCe, there is similar option.

    Any help is highly appreciated.

    Thanks and Regards,
    Swanand
    Thursday, January 14, 2010 1:06 PM
  • Swanand,

    We are looking at adding more creation options in the next version of the framework as we realize that dealing with Create and Skip can be cumbersome. 

    Thanks-
    Phil
    Thursday, January 14, 2010 5:30 PM
    Answerer
  • Perhaps I am missing something, but this does not seem to work with the released version of sync framework 2.0.  It fails when I call apply with the exception "Violation of PRIMARY KEY constraint 'PK_scope_info'. Cannot insert duplicate key in object 'dbo.scope_info'.\r\nThe statement has been terminated."

    The code I am using to protoype this is:

     

    //pull the existing scope description

     

    DbSyncScopeDescription scopeDesc = SqlSyncDescriptionBuilder.GetDescriptionForScope(scopeName, conn);

     

    //Get the list of tables for this scope

     

    List<string> tables = GetTablesForScope(scopeName);

     

    List<string> newTables = new List<string>();

     

    //add tables that do not exist to the scope

     

    foreach (string tablename in tables)

    {

     

    try

    {

     

     

    if (scopeDesc.Tables[tablename] == null)

    {

     

    DbSyncTableDescription tableDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable(tablename, conn);

    scopeDesc.Tables.Add(tableDesc);

    newTables.Add(tablename);

    }

    }

     

    catch (Exception e)

    {

     

    //Log excetption and rethrow

     

    string errorMessage = "Some error";

     

    Logger.WriteLog(...);

     

    throw new Exception(errorMessage, e);

    }

    }

    serverConfig.PopulateFromScopeDescription(scopeDesc);

     

    //for all the existing tables we skip creation of anything

    serverConfig.SetCreateProceduresDefault(

    DbSyncCreationOption.Skip);

    serverConfig.SetCreateProceduresForAdditionalScopeDefault(

    DbSyncCreationOption.Skip);

    serverConfig.SetCreateTableDefault(

    DbSyncCreationOption.Skip);

    serverConfig.SetCreateTrackingTableDefault(

    DbSyncCreationOption.Skip);

    serverConfig.SetCreateTriggersDefault(

    DbSyncCreationOption.Skip);

    serverConfig.SetPopulateTrackingTableDefault(

    DbSyncCreationOption.Skip);

     

    //for all the new tables we create procedures, triggers and the tracking table

     

    // the actual table should already exist in the database

     

    foreach (string tablename in newTables)

    {

    serverConfig.Tables[tablename].CreateProcedures =

    DbSyncCreationOption.Create;

    serverConfig.Tables[tablename].CreateTrackingTable =

    DbSyncCreationOption.Create;

    serverConfig.Tables[tablename].CreateTriggers =

    DbSyncCreationOption.Create;

    }

     

    //provision the server

     

    try

    {

    serverConfig.Apply(conn);

    }

     

    catch (Exception e)

    {

     

    string errorMessage = "Unable to apply scope for scope [" + scopeName + "].";

     

    Logger.WriteLog(...);

     

    throw new Exception(errorMessage, e);

    }


    Nick Caramello
    Wednesday, August 11, 2010 9:44 PM
  • Hi Phil

    We have situation where we need to synchronize millions of records. We found that the Sync Framework takes quite a long time (days!) to complete this process. To overcome this we devised a way where a service on the server side will export the data using BCP to table specific files. The client will download these files and will import the data on the client side using BCP. We are interested in one way sync from the Server to the client.

    We were using Sync Framework 2.0 and since it could not handle table Schema changes we implemented custom logic to manage schema changes. We would typically drop the table on the client and import the data again using BCP. So far so good. We Recently migrated to MS Sync Framework 2.0, thanks to a issue and its resolution provided by June T (http://social.microsoft.com/Forums/en-US/syncdevdiscussions/thread/00b5fb80-ee43-4a94-b401-76408187d22d?prof=required ). However we have retained the custom logic to manage schema changes

    .We have run into a new issue now. I would try to explain the scenario as best as I can.

    At some point the data gets exported to a set of files on the server side. The client downloads and imports the data using BCP at some interval. After successfully importing the data, we are faking the synchronization by clearing the dataset object of type DbSyncContext. We clear this because the data is already imported and we do not want the Sync Framework to start downlaoding the entire data again..

    During this interval there are DML operations on the server data. When the sync process runs next time, it does not pick up the modified/added/deleted rows till that point in time since we faked the previous sync. However in the subsequent synchronizations, newer changes/additions/deletes are synched and not the ones that were missed in the previous step.

    Only the data that has been added/updated/deleted between the the time frame when the backup of table last created on the server and the time when the client first synchs are not reflecting on the client DB.

     

    Friday, September 17, 2010 10:48 AM