public void Merge(string elementNamePrefix, DeltaUpdateDefinition deltaUpdateDefinition)
        {
            foreach (var elementUpdate in deltaUpdateDefinition.ElementsToReplace)
            {
                var newElementName = GetElementNameWithPrefix(elementNamePrefix, elementUpdate.ElementName);
                Set(newElementName, elementUpdate.NewValue);
            }

            foreach (var elementIncrement in deltaUpdateDefinition.ElementsToIncrement)
            {
                var newElementName = GetElementNameWithPrefix(elementNamePrefix, elementIncrement.ElementName);
                Increment(newElementName, elementIncrement.IncrementBy);
            }
        }
        private DeltaUpdateDefinition GetUpdateDefinitionForObject(IObjectDirtyTracker dirtyTracker, Type objectType, object aggregate)
        {
            var updateDefinition = new DeltaUpdateDefinition();
            var classMap         = BsonClassMap.LookupClassMap(objectType);

            foreach (var memberTracker in dirtyTracker.MemberTrackers.Where(t => t.IsDirty))
            {
                if (classMap.ShouldUpdateIncrementally(memberTracker.ElementName))
                {
                    var incrementBy = GetValueDifferenceAsBsonValue(memberTracker);
                    updateDefinition.Increment(memberTracker.ElementName, incrementBy);
                    continue;
                }

                var memberMap      = classMap.GetMemberMapForElement(memberTracker.ElementName);
                var memberClassMap = BsonClassMap.LookupClassMap(memberMap.MemberType);

                if (memberClassMap.ShouldUseDeltaUpdateStrategy())
                {
                    var objectTracker = (IObjectDirtyTracker)memberTracker;
                    var model         = memberMap.Getter(aggregate);

                    if (model == null)
                    {
                        updateDefinition.Set(memberTracker.ElementName, BsonNull.Value);
                        continue;
                    }

                    if (memberTracker.OriginalValue == BsonNull.Value)
                    {
                        updateDefinition.Set(memberTracker.ElementName, memberTracker.CurrentValue);
                        continue;
                    }

                    var subUpdateDefinition = GetUpdateDefinitionForObject(objectTracker, memberMap.MemberType, model);
                    updateDefinition.Merge(memberTracker.ElementName, subUpdateDefinition);
                }
                else
                {
                    updateDefinition.Set(memberTracker.ElementName, memberTracker.CurrentValue);
                }
            }
            return(updateDefinition);
        }