Have you ever wanted to move Taxonomy items from one term store to another? With on-premises implementations you can move your MMS database, but I think this takes to long. What about SharePoint Online? Obviously, we cannot move our database to Office 365 this way. There is an OfficeAMS sample (Core.MMS)  that demonstrates how to perform basic taxonomy operations with the term store however, what if you have use case where you only want to synchronize your changes. This sample takes the Core.MMS sample a step further, by using the ChangeInformation class in the Microsoft.SharePoint.Client.Taxonomy assembly to synchronize your term stores.

This sample will use the ChangeInformation class to return all the changes in the source term store. 

First, create a TaxonomySession object. 

DateTime _startFrom = DateTime.Now.AddYears(-1);

Console.WriteLine("Opening the taxonomy session");
TaxonomySession _sourceTaxonomySession = TaxonomySession.GetTaxonomySession(sourceClientContext);
TermStore sourceTermStore = _sourceTaxonomySession.GetDefaultKeywordsTermStore();
sourceClientContext.Load(sourceTermStore);
sourceClientContext.ExecuteQuery();

Once you have created the TaxonomySession object we need to get the changes, we get the changes by creating a new Instance of ChangeInformation and set the start date. In this case, I’m getting all the changes from 1 year ago. 

Console.WriteLine("Reading the changes");
ChangeInformation _ci = new ChangeInformation(sourceClientContext);
_ci.StartTime = _startFrom;
ChangedItemCollection _cic = sourceTermStore.GetChanges(_ci);
sourceClientContext.Load(_cic);
sourceClientContext.ExecuteQuery();

Once we invoke the GetChanges member this will return a ChangeItemCollection that can be used to enumerate the changes that have occurred in term store. You can then perform an operation on the target term store like add, edit or delete like we do in the downloadable code sample.

foreach (ChangedItem _changeItem in _cic) {
///ENUMERATE YOU’RE CHANGES
if (_changeItem.ItemType == ChangedItemType.Group){
///PROCESS YOU’RE CHANGES
}
}

 

Running the code.

 

 

Ensure, that the user has the appropriate permissions to the term store in both the source and target term stores, or you will get an exception.

 

FAQ

Question - "Does this work with on-premises SharePoint implementations?" 

Sure does, in the code sample change SharePointOnlineCredentials to NetworkCredential

Question - "I need my Guid in the target Termstore, does this preserve the Guid?" 

Yes, the code sample will retain you Guid

Question - "Why should i use this pattern to sync my terms?"

This performs better  than just GetAllTerms and enumerating every time you want to sync. 

 Question - "Does this work with SharePoint 2010?"

In theory yes, however you should only use SharePoint 2010 as the source and not the target.  We are unable to set the TermId in CSOM for 2010.

References

Few useful links and resources related on this blog post

Code example from this blog post. - "Core.MMSSync.zip" 

 

Special thanks to Kimmo Forss