/// <summary>
        /// bulk save sliced child change actions
        /// </summary>
        /// <param name="page">a page/slice of child change actions</param>
        internal void BatchSaveChangeActions(IList <IMigrationAction> page)
        {
            Debug.Assert(m_runTimeChangeGroup != null);

            const int bulkChangeActionInsertionSize = 1000;
            int       changeActionCount             = 0;
            int       pageIndex = 0;

            while (pageIndex < page.Count)
            {
                using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
                {
                    RTChangeGroup rtChangeGroupCache = getNativeRTChangeGroup(context);
                    Debug.Assert(null != rtChangeGroupCache);

                    while (pageIndex < page.Count && changeActionCount < bulkChangeActionInsertionSize)
                    {
                        SqlMigrationAction action = page[pageIndex] as SqlMigrationAction;
                        Debug.Assert(null != action);

                        // cache "Dirty" flag, as assignin 'this' to its ChangeGroup will set the flag to true
                        bool actionWasDirty = action.IsDirty;
                        action.ChangeGroup = this;

                        if (!action.IsPersisted)
                        {
                            IMigrationItemSerializer serializer = ManagerWithMigrationItemSerializers[action.Action];
                            action.CreateNew(serializer);
                            context.AddToRTChangeActionSet(action.RTChangeAction);
                            action.RTChangeAction.ChangeGroup = rtChangeGroupCache;
                            ++changeActionCount;
                        }
                        else if (actionWasDirty)
                        {
                            IMigrationItemSerializer serializer     = ManagerWithMigrationItemSerializers[action.Action];
                            RTChangeAction           rtChangeAction = action.RTChangeAction;
                            if (null != rtChangeAction)
                            {
                                rtChangeAction = context.GetObjectByKey(rtChangeAction.EntityKey) as RTChangeAction;
                            }
                            else
                            {
                                rtChangeAction = context.RTChangeActionSet.Where(ca => ca.ChangeActionId == action.ActionId).First();
                            }

                            rtChangeAction.Recursivity           = action.Recursive;
                            rtChangeAction.IsSubstituted         = action.State == ActionState.Skipped ? true : false;
                            rtChangeAction.ActionId              = action.Action;
                            rtChangeAction.SourceItem            = serializer.SerializeItem(action.SourceItem);
                            rtChangeAction.ToPath                = action.Path;
                            rtChangeAction.ItemTypeReferenceName = action.ItemTypeReferenceName;
                            rtChangeAction.FromPath              = action.FromPath;
                            rtChangeAction.Version               = action.Version;
                            rtChangeAction.MergeVersionTo        = action.MergeVersionTo;

                            if (action.MigrationActionDescription != null &&
                                action.MigrationActionDescription.DocumentElement != null)
                            {
                                rtChangeAction.ActionData = action.MigrationActionDescription.DocumentElement.OuterXml;
                            }
                            ++changeActionCount;
                        }

                        ++pageIndex;
                    }
                    context.TrySaveChanges();
                    changeActionCount = 0;
                }
            }
        }
        protected override void Create()
        {
            // ToDo
            ChangeStatus targetStatus = Status;

            SqlChangeGroupManager manager = this.Manager as SqlChangeGroupManager;

            Debug.Assert(null != manager, "Manager is not a SqlChangeGroupManager for SqlChangeGroup");

            // save the group (without child actions)
            SavePartialChangeGroup();

            // bulk save sliced child change actions
            const int bulkChangeActionInsertionSize = 1000;
            int       changeActionCount             = 0;

            while (Actions.Count > 0)
            {
                using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
                {
                    try
                    {
                        context.Attach(m_runTimeChangeGroup);

                        while (Actions.Count > 0 && changeActionCount < bulkChangeActionInsertionSize)
                        {
                            SqlMigrationAction action = Actions[0] as SqlMigrationAction;
                            Debug.Assert(null != action);
                            action.ChangeGroup = this;

                            IMigrationItemSerializer serializer = ManagerWithMigrationItemSerializers[action.Action];
                            action.CreateNew(serializer);
                            action.RTChangeAction.ChangeGroup = m_runTimeChangeGroup;

                            // Remove processed child change actions.
                            // When this ObjectModel context is disposed,
                            // the RTChangeAction will be disposed as well.
                            Actions.RemoveAt(0);

                            ++changeActionCount;
                        }
                        context.TrySaveChanges();
                    }
                    finally
                    {
                        context.Detach(m_runTimeChangeGroup);
                    }
                }

                changeActionCount = 0;
            }

            // update group status in DB
            using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
            {
                try
                {
                    context.Attach(m_runTimeChangeGroup);
                    m_runTimeChangeGroup.Status          = (int)targetStatus;
                    m_runTimeChangeGroup.UsePagedActions = m_usePagedActions;
                    context.TrySaveChanges();
                }
                finally
                {
                    context.Detach(m_runTimeChangeGroup);
                }
            }
        }