Exemple #1
0
        /// <summary>
        /// 执行数据归档。
        /// </summary>
        public void ExecuteArchivingData()
        {
            var condition = new CommonQueryCriteria(BinaryOperator.And)
            {
                new PropertyMatch(EntityStampExtension.UpdatedTimeProperty, PropertyOperator.LessEqual, this._context.DateOfArchiving)
            };

            condition.PagingInfo = new PagingInfo(1, this._context.PageSize);

            var aggregationRootParameters = _context.ArchivingAggregationRootTypeList;

            this.Report(new DataTableMigrationEventArgs("-------------- 开始数据归档 --------------"));

            foreach (var parameter in aggregationRootParameters)
            {
                var currentProcess = 0M;
                var repository     = this.FindRepository(parameter);
                var totalCount     = repository.CountBy(new CommonQueryCriteria {
                    new PropertyMatch(EntityStampExtension.UpdatedTimeProperty, PropertyOperator.LessEqual, this._context.DateOfArchiving)
                });

                this.Report(new DataTableMigrationEventArgs($"共有 {totalCount} 个聚合根 {parameter.FullName} 需要归档。"));

                var eagerLoadOptions = new EagerLoadOptions();

                bool isHasChild = false;

                LoadChildListProperty(ref isHasChild, repository.EntityMeta, eagerLoadOptions);

                bool isSupportTree = repository.SupportTree;

                if (isSupportTree)
                {
                    eagerLoadOptions.LoadWithTreeChildren();
                }

                if (isHasChild || isSupportTree)
                {
                    condition.EagerLoad = eagerLoadOptions;
                }

                var entityList = repository.GetBy(condition);

                while (entityList != null && entityList.Count > 0)
                {
                    this.SaveToHistory(repository, entityList, isSupportTree);

                    //实体删除
                    this.RemoveOriginData(repository, entityList);

                    currentProcess = currentProcess + entityList.Count;
                    this.Report(new DataTableMigrationEventArgs($"\t处理进度", decimal.Round(currentProcess / totalCount * 100, 2)));

                    entityList = repository.GetBy(condition);
                }
            }

            this.Report(new DataTableMigrationEventArgs("-------------- 结束数据归档 --------------"));
        }
Exemple #2
0
        /// <summary>
        /// 执行数据归档。
        /// </summary>
        /// <param name="context">表示数据归档的上下文。</param>
        public void Archive(AggregationArchiveContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            _orignalDataDbSettingName = context.OrignalDataDbSettingName;
            _backUpDbSettingName      = context.BackUpDbSettingName;

            var updatedTimeCondition = new PropertyMatch(EntityStampExtension.UpdatedTimeProperty, PropertyOperator.LessEqual, context.DateOfArchiving);

            bool needProgress = this.ProgressChanged != null;

            if (needProgress)
            {
                this.OnProgressChanged("-------------- 开始数据归档 --------------");
            }

            using (StampContext.DisableAutoSetStamps())
            {
                foreach (var item in context.ItemsToArchive)
                {
                    var aggtRootType = item.AggregationRoot;
                    var archiveType  = item.ArchiveType;
                    if (archiveType == ArchiveType.Copy)
                    {
                        throw new NotSupportedException("Copy 操作暂不支持。");
                    }

                    var repository = RepositoryFacade.Find(aggtRootType);

                    #region 查询本次需要归档的总数据行数。

                    long totalCount = 0;
                    if (needProgress)
                    {
                        totalCount = repository.CountBy(new CommonQueryCriteria {
                            updatedTimeCondition
                        });
                        this.OnProgressChanged($"目前,共有 {totalCount} 个聚合根 {aggtRootType.FullName} 需要归档。");
                    }

                    #endregion

                    #region 构造一个查完整聚合的条件对象 CommonQueryCriteria

                    //设置 EagerLoadOptions,加载整个聚合。
                    var criteria = new CommonQueryCriteria()
                    {
                        updatedTimeCondition
                    };
                    criteria.PagingInfo = new PagingInfo(1, context.BatchSize);
                    var eagerLoadOptions = new EagerLoadOptions();
                    EagerLoadAggregationRecur(eagerLoadOptions, repository.EntityMeta);
                    if (repository.SupportTree)
                    {
                        eagerLoadOptions.LoadWithTreeChildren();
                    }
                    criteria.EagerLoad = eagerLoadOptions;

                    #endregion

                    //逐页迁移历史数据表。
                    var currentProcess = 0;
                    while (true)
                    {
                        //获取最新的一页的数据。
                        var entitiesToMigrate = repository.GetBy(criteria);
                        var count             = entitiesToMigrate.Count;
                        if (count == 0)
                        {
                            break;
                        }

                        using (var tranOriginal = RF.TransactionScope(_orignalDataDbSettingName))
                            using (var tranBackup = RF.TransactionScope(_backUpDbSettingName))
                            {
                                //迁移到历史表。
                                this.BackupToHistory(repository, entitiesToMigrate);

                                //实体删除
                                this.DeleteOriginalData(repository, entitiesToMigrate);

                                //备份完成,才能同时提交两个库的事务。
                                tranOriginal.Complete();
                                tranBackup.Complete();
                            }

                        currentProcess += count;

                        if (needProgress)
                        {
                            this.OnProgressChanged($"    处理进度", decimal.Round(currentProcess / totalCount * 100, 2));
                        }
                    }
                }
            }

            if (needProgress)
            {
                this.OnProgressChanged("-------------- 结束数据归档 --------------");
            }
        }