INotifyingChangeApplierTarget::SaveChangeWithChangeUnits Method
When overridden in a derived class, saves an item change that contains unit change changes to the item store.
Assembly: Microsoft.Synchronization (in Microsoft.Synchronization.dll)
void SaveChangeWithChangeUnits(
ItemChange^ change,
SaveChangeWithChangeUnitsContext^ context
)
Parameters
- change
- Type: Microsoft.Synchronization::ItemChange
The item change to apply.
- context
- Type: Microsoft.Synchronization::SaveChangeWithChangeUnitsContext
Information about the change to be applied.
When the action that is contained in context is Create, the item change must be saved atomically. This means that either all of the change units must be saved successfully or the entire item change must be discarded. Saving some of the change units and failing to save others can result in data corruption.
When RecordRecoverableErrorForChangeUnit is called and context is Create, RecordRecoverableErrorForChangeUnit throws the CreateFailuresMustBeForEntireItemException.
If synchronization is canceled during this method, and the provider has applied some of the change units, the provider must call RecordRecoverableErrorForChangeUnit on all change units that are not applied.
The following example shows how to handle some of the most common SaveChangeAction values in the SaveChangeWithChangeUnits method.
Public Sub SaveChangeWithChangeUnits(ByVal change As ItemChange, ByVal context As SaveChangeWithChangeUnitsContext) Implements INotifyingChangeApplierTarget.SaveChangeWithChangeUnits ' Enumerate the change units received and apply them by using the specified action. For Each cuChange As ChangeUnitChange In change.ChangeUnitChanges Select Case context.GetActionForChangeUnit(cuChange) Case SaveChangeAction.Create, SaveChangeAction.UpdateVersionAndData If True Then ' Update the item store and metadata store for the specified change unit. Try Dim cuData As String = DirectCast(context.ChangeData, String())(cuChange.ChangeUnitId.GetByteId()) _ContactStore.UpdateContactFromSync(change, cuChange, cuData) Catch ex As Exception Dim errData As New RecoverableErrorData(ex) context.RecordRecoverableErrorForChangeUnit(cuChange, errData) End Try Exit Select End If Case SaveChangeAction.UpdateVersionAndMergeData If True Then ' Merge actions are not supported by this implementation. Throw New NotImplementedException("UpdateVersionAndMergeData is not supported.") End If Case SaveChangeAction.UpdateVersionOnly If True Then ' Update only the version of this change unit in the metadata store. Try _ContactStore.UpdateContactVersion(change.ItemId, cuChange.ChangeUnitId, cuChange.ChangeUnitVersion) Catch ex As Exception Dim errData As New RecoverableErrorData(ex) context.RecordRecoverableErrorForChangeUnit(cuChange, errData) End Try Exit Select End If Case SaveChangeAction.DeleteAndRemoveTombstone, SaveChangeAction.DeleteAndStoreTombstone If True Then ' Delete actions are handled in SaveItemChange, so throw an exception. Throw New InvalidOperationException("SaveChangeWithChangeUnits received a delete action.") End If Case Else If True Then Throw New ArgumentOutOfRangeException("SaveChangeWithChangeUnits received an out-of-range action.") End If End Select Next ' Use the metadata storage service to save the knowledge as each change is applied. Saving knowledge as each change is applied is ' not required. It is more robust than saving the knowledge only after each change batch, because if synchronization is interrupted ' before the end of a change batch, the knowledge will still reflect all of the changes applied. However, it is less efficient because ' knowledge must be stored more frequently. Dim updatedKnowledge As SyncKnowledge = Nothing Dim updatedForgottenKnowledge As ForgottenKnowledge = Nothing context.GetUpdatedDestinationKnowledge(updatedKnowledge, updatedForgottenKnowledge) _ContactStore.ContactReplicaMetadata.SetKnowledge(updatedKnowledge) End Sub
public void SaveChangeWithChangeUnits(ItemChange change, SaveChangeWithChangeUnitsContext context) { // Enumerate the change units received and apply them by using the specified action. foreach (ChangeUnitChange cuChange in change.ChangeUnitChanges) { switch (context.GetActionForChangeUnit(cuChange)) { case SaveChangeAction.Create: case SaveChangeAction.UpdateVersionAndData: { // Update the item store and metadata store for the specified change unit. try { string cuData = ((string[])context.ChangeData)[cuChange.ChangeUnitId.GetByteId()]; _ContactStore.UpdateContactFromSync(change, cuChange, cuData); } catch (Exception ex) { RecoverableErrorData errData = new RecoverableErrorData(ex); context.RecordRecoverableErrorForChangeUnit(cuChange, errData); } break; } case SaveChangeAction.UpdateVersionAndMergeData: { // Merge actions are not supported by this implementation. throw new NotImplementedException("UpdateVersionAndMergeData is not supported."); } case SaveChangeAction.UpdateVersionOnly: { // Update only the version of this change unit in the metadata store. try { _ContactStore.UpdateContactVersion(change.ItemId, cuChange.ChangeUnitId, cuChange.ChangeUnitVersion); } catch (Exception ex) { RecoverableErrorData errData = new RecoverableErrorData(ex); context.RecordRecoverableErrorForChangeUnit(cuChange, errData); } break; } case SaveChangeAction.DeleteAndRemoveTombstone: case SaveChangeAction.DeleteAndStoreTombstone: { // Delete actions are handled in SaveItemChange, so throw an exception. throw new InvalidOperationException("SaveChangeWithChangeUnits received a delete action."); } default: { throw new ArgumentOutOfRangeException("SaveChangeWithChangeUnits received an out-of-range action."); } } } // Use the metadata storage service to save the knowledge as each change is applied. Saving knowledge as each change is applied is // not required. It is more robust than saving the knowledge only after each change batch, because if synchronization is interrupted // before the end of a change batch, the knowledge will still reflect all of the changes applied. However, it is less efficient because // knowledge must be stored more frequently. SyncKnowledge updatedKnowledge; ForgottenKnowledge updatedForgottenKnowledge; context.GetUpdatedDestinationKnowledge(out updatedKnowledge, out updatedForgottenKnowledge); _ContactStore.ContactReplicaMetadata.SetKnowledge(updatedKnowledge); }