How do I implement DataSetSurrogates in my VS2008 Sync Services App? RRS feed

  • Question

  • Due to one large table in my Sync Services application causing memory errors on a sync, I am attempting to utilize the DataSetSurrogate class to reduce the size of the data set that I'm transferring. I've been scouring the web trying to find a real world example of how to actually implement it, (not a Microsoft Northwind example) but so far I haven't had any luck. I'm hoping someone can help me fill in the blanks below on how I would implement this for a WCF service and VS2008 C# application (having taken advantage of the Sync Services wizard to get the project started).

    My first question is around how I can pass my DataSetSurrogate to my webservice from my client during the synchronization call? Do I have to define my SyncAgent differently to enable the DataSetSurrogate class to get passed along when I perform a Synchronize()? 

    My second question is how my WCF would receive the new dataSetSurrogate? Do I modify my "ApplyChanges" function to accept a DataSetSurrogate class type and then do the conversion back to a dataset here? 


    public virtual SyncContext ApplyChanges(SyncGroupMetadata groupMetadata, DataSetSurrogate dataSetSurrogate, SyncSession syncSession) {

    DataSet dataSet - dataSetSurrogate.ConvertToDataSet();

    SyncContext changes = this._serverSyncProvider.ApplyChanges(groupMetadata, dataSet, syncSession);
    return changes;


    catch (SyncException se)
    if (se.ErrorNumber == SyncErrorNumber.StoreException){
    SqlException sqlExcept = se.InnerException as SqlException; if (sqlExcept != null && sqlExcept.Class == 16 && sqlExcept.State == 3)
    throw new ApplicationException("ChangeTrackingCleanedUp", se);}
    throw se;


    catch (Exception e)


    throw e;

    If so, then once the changes have been applied and it's time to send the data set back to the client, how do I handle sending the dataSetSurrogate class back across? Would it go through GetChanges?

    Thanks for any advice to help get me pointed in the right direction.





    Friday, March 5, 2010 11:51 PM


All replies

  • you're on the right track. you would do the same change to your GetChanges. The GetChanges returns a SyncContext and inside the SyncContext is a dataset containing the changes (SyncContext.Dataset). 

    If i remember it right, what i did before was to change the return value of the GetChanges to a DatasetSurrogate. In the  WCF code for GetChanges, i grab the SyncContext.Dataset convert it to a DataSetSurrogate and return the DataSetSurrogate. On the client side WCF proxy, i convert the DatasetSurrogate back to a Dataset and assign back the Dataset to the SyncContext.Dataset.

    btw, in your WCF ApplyChanges, you are returning a SyncContext. That SyncContext contains a dataset again and some conflict information under GroupProgress. If you're not going to do anything with those dataset in the client, you can clear the dataset before returning the syncontext (i.e, your variable named "changes")

    Saturday, March 6, 2010 2:08 AM
  • hi Matt,

    you'll find an example here: http://jtabadero.spaces.live.com/blog/cns!BF49A449953D0591!1187.entry


    • Marked as answer by MattMJB Wednesday, March 10, 2010 4:22 PM
    Monday, March 8, 2010 3:14 PM
  • Thanks for the example, it will be very helpful.

    I am going to look at implementing the dataset surrogate for a future release of my app and will update this thread with my results.

    It does seem fairly involved, so hopefully at some point Microsoft can provide a straight forward solution for dealing with large data sets.

    Wednesday, March 10, 2010 4:22 PM
  • not that complex really. you just need to change your getchanges and applychanges on server and client side (via the proxy).

    if you use V2 collaborattion providers, there's built-in support for memory-based batching (which internally converts the dataset to a datasetsurrogate
    Wednesday, March 10, 2010 4:31 PM