Deploying and Versioning Applications (Synchronization Services)

The way in which you deploy an application that uses Synchronization Services depends on whether the application is two-tier or N-tier. In a two-tier application, all the synchronization code is on the client, and the application can be deployed like any other application that is based on SQL Server Compact 3.5. Typically, deployment involves either using ClickOnce to publish the application or packaging the application and then copying it to each client. For more information about how to deploy applications that use SQL Server Compact 3.5, see the topics "Deploying Applications" and "How to: Build and Deploy an Application to a Desktop" in SQL Server Compact 3.5 Books Online. In an N-tier application, you must also deploy code to the computer that hosts the server-side synchronization components.

For two-tier and N-tier applications, you must decide how to create and initialize the client database that has the schema and data that the application requires. There are two main approaches:

  • Use Synchronization Services to create the database, and download the table schema and data during the first synchronization. This is the simplest approach. However, it might require a lot of network traffic and server processing if you have many clients and a large set of data.
  • Pre-create the database that has the table schema and an initial data set. The database, which is in the form of an .sdf file, can be transported or downloaded by the client application. If the application downloads incremental changes, it can bring the client database up-to-date during the first synchronization. If you use this approach, set an appropriate value for the CreationOption property.
    If the application includes uploads and you want to know where changes originated, the application can set the ClientId property to uniquely identify the client database to the server; or Synchronization Services will generate a new ID for the database.
    Pre-creating the client database is not suitable for applications in which data is filtered differently for each client. It can cause missed changes during the initial synchronization.

For more information about how to initialize the client database, see How to: Initialize the Client Database and Work with Table Schema.

After an application has been developed and deployed, new versions of the application might be developed. There are two areas to consider for application versioning:

  • The parts of the application that are affected by a new version
  • Whether a new version must coexist with earlier versions

Generally, an N-tier application is easier to update for Synchronization Services because you can update the server-side components separately from the client-side components. This can help shield clients from server-side changes until they are ready to have client-side components updated.

Versioning for N-tier Applications

For Synchronization Services, the main application update to consider is a schema change to the server database. Synchronization Services does not automatically propagate schema changes from the server to the client. However, it does support schema changes as long as you update the appropriate parts of the application. For a list of schema changes that are supported in the client database, see Working with Table Schemas (Synchronization Services). If a schema change is made in the server database, you should first decide whether it must be propagated to the client at all. For example, if you add a credit card column to a table in the server database but you have a business rule that disallows employees from taking credit card information offline, you do not have to propagate the schema change to the client. If you decide to propagate the schema change, how you do this depends on the type of change.

Common Schema Changes

The two most common schema changes are adding a column to an existing table and adding a new table, or deciding to include an existing table that was not originally part of the application. If the application requires a new table to be synchronized, you must add a SyncAdapter for the table. After the server components are updated, the client application or the user of the application can determine whether to synchronize the new table. If the decision is to synchronize the new table, the client components must be changed to include a SyncTable for the new table. These changes must be pushed out to each client application in some way. ClickOnce technology enables you to publish application updates, and applications can check for any updates before they start. If you add a new column to a table and want that column to be synchronized, you must add the column to the client database and update the commands that are used to synchronize changes. For schema changes other than adding a new column, drop the table on the client and re-create it by using Synchronization Services or another mechanism.

Coexisting Versions

In some scenarios, the new and old versions of a client application might have to coexist. In such cases, you can take two different approaches:

  • Maintain multiple versions of the server components so that an older version of the client components can continue to access the appropriate version of the server components.
  • Design the client and server components to use an application version parameter. This approach enables the client application to notify the server about which version it expects. Consider the following example in which the stored procedure that selects inserts from the server accepts an @appversion parameter. A parameter is added to the SelectIncrementalInsertsCommand, and then a value is supplied by using a SyncParameter in the SyncAgent. When synchronization occurs, the application version is sent to the server, and the stored procedure selects the correct version of the table schema.
          new SyncParameter("@appversion", 1));
    customerIncrUpdates.Parameters.Add("@appversion", SqlDbType.Int);

    Me.Configuration.SyncParameters.Add( _
          New SyncParameter("@appversion", 1))
    customerIncrUpdates.Parameters.Add("@appversion", SqlDbType.Int); 

    CREATE PROCEDURE usp_CustomerSelectIncrementalInserts(
        @sync_last_received_anchor timestamp, 
        @sync_new_received_anchor timestamp, 
        @appversion int
        IF @appversion = 1
            SELECT CustomerId, CustomerName, SalesPerson
            FROM Sales.Customer 
            WHERE InsertTimestamp > @sync_last_received_anchor 
            AND InsertTimestamp <= @sync_new_received_anchor
        ELSE IF @appversion = 2
            SELECT CustomerId, CustomerName, SalesPerson, CustomerType
            FROM Sales.Customer 
            WHERE InsertTimestamp > @sync_last_received_anchor 
            AND InsertTimestamp <= @sync_new_received_anchor
            PRINT('Unrecognized version')