Exemple #1
0
        /// <summary>
        /// 导入数据到关系数据库
        /// </summary>
        /// <param name="mode">导入模式</param>
        /// <param name="isNew">导入模式为更新模式的时候,进行实体类数据新旧比较的自定义方法,第一个参数为源实体,第二个参数为数据库的目标实体,返回源是否比目标新</param>
        /// <returns>导入的数据数量</returns>
        public ImportResult Import(ImportMode mode, Func <T, T, bool> isNew)
        {
            Type         entityType      = typeof(T);
            string       importTableName = EntityFieldsCache.Item(entityType).TableName;
            ImportResult result          = new ImportResult();

            result.ImportTable = importTableName;
            result.IsCancel    = true;

            //导出批次管理
            string memDbPath = this.MemDB.Path;
            string pkgPath   = memDbPath.Length > 255 ? memDbPath.Substring(memDbPath.Length - 255) : memDbPath;
            List <ExportBatchInfo> batchList = MemDB.Get <ExportBatchInfo>();
            ExportBatchInfo        currBatch = batchList.FirstOrDefault(p => p.ExportTableName == importTableName);

            if (currBatch == null)
            {
                result.Flag = ImportResultFlag.NoBatchInfo;
                return(result);//没有导入批次信息,不能导入
            }
            //只有比数据库的导入批次数据新,才可以导入

            currBatch.PackagePath = pkgPath;
            OQL q = OQL.From(currBatch)
                    .Select()
                    .Where(currBatch.ExportTableName, currBatch.PackagePath)
                    .END;
            ExportBatchInfo dbBatch = this.CurrDbContext.QueryObject <ExportBatchInfo>(q);

            if (dbBatch == null)
            {
                currBatch.SetDefaultChanges();
                this.CurrDbContext.Add <ExportBatchInfo>(currBatch);
                result.BatchNumber = currBatch.BatchNumber;
            }
            else
            {
                result.BatchNumber = currBatch.BatchNumber;
                if (currBatch.BatchNumber <= dbBatch.BatchNumber)
                {
                    result.Flag = ImportResultFlag.IsOldData;
                    return(result);//没有新数据需要导入
                }
                currBatch.ID = dbBatch.ID;
            }

            //导入数据
            int      count = 0;//
            List <T> list  = this.MemDB.Get <T>();

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            if (list.Count > 0)
            {
                ImportEntityEventArgs <T> args = new ImportEntityEventArgs <T>(list, entityType, importTableName, currBatch.BatchNumber);
                if (BeforeImport != null)
                {
                    BeforeImport(this, args);
                    if (args.Cancel)
                    {
                        result.Flag = ImportResultFlag.UserCanceled;
                        return(result);
                    }
                }
                //处理不同的导入模式
                if (mode == ImportMode.Append)
                {
                    list.ForEach(item => {
                        item.ResetChanges(true);
                    });
                    count = this.CurrDbContext.AddList(list);
                }
                else if (mode == ImportMode.TruncateAndInsert)
                {
                    string sql = "TRUNCATE TABLE [" + importTableName + "]";
                    this.CurrDbContext.CurrentDataBase.ExecuteNonQuery(sql);
                    //list.ForEach(item =>
                    //{
                    //    item.SetDefaultChanges();
                    //});
                    //count = this.CurrDbContext.AddList(list);
                    list[0].ResetChanges(true);
                    EntityQuery <T> eq = new EntityQuery <T>(this.CurrDbContext.CurrentDataBase);
                    count = eq.QuickInsert(list);
                }
                else if (mode == ImportMode.Update)
                {
                    if (isNew == null)
                    {
                        throw new ArgumentNullException("当 ImportMode 为Update 模式的时候,参数 isNew 不能为空。");
                    }
                    foreach (T item in list)
                    {
                        T           dbEntity = (T)item.Clone();
                        EntityQuery eq       = new EntityQuery(this.CurrDbContext.CurrentDataBase);
                        if (eq.FillEntity(dbEntity))
                        {
                            if (isNew(item, dbEntity))
                            {
                                item.ResetChanges(true);; //设置了更改状态,才可以更新到数据库
                                count += eq.Update(item);
                            }
                        }
                    }
                }
                else if (mode == ImportMode.Merge)
                {
                    /*
                     * //下面的方式比较缓慢,改用先删除数据包对应的数据再快速插入的方式
                     * foreach (T item in list)
                     * {
                     *  T dbEntity = (T)item.Clone();
                     *  EntityQuery eq = new EntityQuery(this.CurrDbContext.CurrentDataBase);
                     *  if (eq.FillEntity(dbEntity))
                     *  {
                     *      int changedCount = dbEntity.MapFrom(item, true);
                     *      if (changedCount > 0)
                     *      {
                     *         count+= eq.Update(dbEntity);
                     *      }
                     *  }
                     *  else
                     *  {
                     *      //没有Fill成功实体,说明数据库没有此数据,则添加数据到数据库
                     *      item.SetDefaultChanges();
                     *      count+= eq.Insert(item);
                     *  }
                     * }
                     * //
                     */
                    var idList = list.Select(s => s[s.PrimaryKeys[0]]).ToList();
                    //每页大小  
                    const int pageSize = 500;
                    //页码  
                    int pageNum = 0;
                    T   entity  = new T();
                    list[0].ResetChanges(true);
                    EntityQuery <T> eq = new EntityQuery <T>(this.CurrDbContext.CurrentDataBase);
                    this.CurrDbContext.CurrentDataBase.BeginTransaction();
                    try
                    {
                        while (pageNum * pageSize < idList.Count)
                        {
                            var currIdList = idList.Skip(pageSize * pageNum).Take(pageSize);
                            var deleteQ    = OQL.From(entity)
                                             .Delete()
                                             .Where(cmp => cmp.Comparer(entity[entity.PrimaryKeys[0]], "in", currIdList.ToArray()))
                                             .END;
                            int deleteCount = eq.ExecuteOql(deleteQ);
                            pageNum++;
                        }
                        count = eq.QuickInsert(list);
                        this.CurrDbContext.CurrentDataBase.Commit();
                    }
                    catch (Exception ex)
                    {
                        count = 0;
                        this.CurrDbContext.CurrentDataBase.Rollback();

                        result.IsCancel     = true;
                        result.Flag         = ImportResultFlag.Error;
                        result.ImportCount  = count;
                        result.ErrorMessage = ex.Message;
                        if (ex.InnerException != null)
                        {
                            QueryException qe = ex.InnerException as QueryException;
                            if (qe != null)
                            {
                                result.ErrorMessage += ":QueryException :" + qe.Message;
                            }
                            else
                            {
                                result.ErrorMessage += ":Error :" + ex.InnerException.Message;
                            }
                        }
                        return(result);
                    }
                }
                else
                {
                    //自定义的处理方式,请在 BeforeImport 事件自行处理
                }

                if (AfterImport != null)
                {
                    args.Cancel = false;
                    AfterImport(this, args);
                }
            }//end if
            //更新导入批次信息
            currBatch.BatchNumber    = result.BatchNumber;
            currBatch.LastExportDate = DateTime.Now;
            this.CurrDbContext.Update <ExportBatchInfo>(currBatch);

            watch.Stop();
            result.Duration    = Convert.ToInt64(watch.Elapsed.TotalSeconds);
            result.IsCancel    = false;
            result.Flag        = ImportResultFlag.Succeed;
            result.ImportCount = count;
            return(result);
        }
        /// <summary>
        /// 导入数据到关系数据库
        /// </summary>
        /// <typeparam name="T">实体类类型</typeparam>
        /// <param name="mode">导入模式</param>
        /// <param name="isNew">导入模式为更新模式的时候,进行实体类数据新旧比较的自定义方法,第一个参数为源实体,第二个参数为数据库的目标实体,返回源是否比目标新</param>
        /// <returns>导入的数据数量</returns>
        public ImportResult Import <T>(ImportMode mode, Func <T, T, bool> isNew) where T : EntityBase, new()
        {
            Type         entityType      = typeof(T);
            string       importTableName = EntityFieldsCache.Item(entityType).TableName;
            ImportResult result          = new ImportResult();

            result.ImportTable = importTableName;
            result.IsCancel    = true;

            //导出批次管理
            List <ExportBatchInfo> batchList = MemDB.Get <ExportBatchInfo>();
            ExportBatchInfo        currBatch = batchList.FirstOrDefault(p => p.ExportTableName == importTableName);

            if (currBatch == null)
            {
                result.Flag = ImportResultFlag.NoBatchInfo;
                return(result);//没有导入批次信息,不能导入
            }
            //只有比数据库的导入批次数据新,才可以导入
            OQL q = OQL.From(currBatch)
                    .Select()
                    .Where(currBatch.ExportTableName)
                    .END;
            ExportBatchInfo dbBatch = this.CurrDbContext.QueryObject <ExportBatchInfo>(q);

            if (dbBatch == null)
            {
                currBatch.SetDefaultChanges();
                this.CurrDbContext.Add <ExportBatchInfo>(currBatch);
                result.BatchNumber = currBatch.BatchNumber;
            }
            else
            {
                result.BatchNumber = currBatch.BatchNumber;
                if (currBatch.BatchNumber <= dbBatch.BatchNumber)
                {
                    result.Flag = ImportResultFlag.IsOldData;
                    return(result);//没有新数据需要导入
                }
                currBatch.ID = dbBatch.ID;
            }

            //导入数据
            int      count = 0;//
            List <T> list  = this.MemDB.Get <T>();

            if (list.Count > 0)
            {
                ImportEntityEventArgs args = new ImportEntityEventArgs(list, entityType, importTableName, currBatch.BatchNumber);
                if (BeforeImport != null)
                {
                    BeforeImport(this, args);
                    if (args.Cancel)
                    {
                        result.Flag = ImportResultFlag.UserCanceled;
                        return(result);
                    }
                }

                if (mode == ImportMode.Append)
                {
                    list.ForEach(item => {
                        item.SetDefaultChanges();
                    });
                    count = this.CurrDbContext.AddList(list);
                }
                else if (mode == ImportMode.TruncateAndInsert)
                {
                    string sql = "TRUNCATE TABLE [" + importTableName + "]";
                    this.CurrDbContext.CurrentDataBase.ExecuteNonQuery(sql);
                    list.ForEach(item =>
                    {
                        item.SetDefaultChanges();
                    });
                    count = this.CurrDbContext.AddList(list);
                }
                else if (mode == ImportMode.Update)
                {
                    if (isNew == null)
                    {
                        throw new ArgumentNullException("当 ImportMode 为Update 模式的时候,参数 isNew 不能为空。");
                    }
                    foreach (T item in list)
                    {
                        T           dbEntity = (T)item.Clone();
                        EntityQuery eq       = new EntityQuery(this.CurrDbContext.CurrentDataBase);
                        if (eq.FillEntity(dbEntity))
                        {
                            if (isNew(item, dbEntity))
                            {
                                item.SetDefaultChanges();//设置了更改状态,才可以更新到数据库
                                count += eq.Update(item);
                            }
                        }
                    }
                }
                else if (mode == ImportMode.Merge)
                {
                    foreach (T item in list)
                    {
                        T           dbEntity = (T)item.Clone();
                        EntityQuery eq       = new EntityQuery(this.CurrDbContext.CurrentDataBase);
                        if (eq.FillEntity(dbEntity))
                        {
                            int changedCount = dbEntity.MapFrom(item, true);
                            if (changedCount > 0)
                            {
                                count += eq.Update(dbEntity);
                            }
                        }
                        else
                        {
                            //没有Fill成功实体,说明数据库没有此数据,则添加数据到数据库
                            item.SetDefaultChanges();
                            count += eq.Insert(item);
                        }
                    }
                }
                else
                {
                    //自定义的处理方式,请在 BeforeImport 事件自行处理
                }

                if (AfterImport != null)
                {
                    args.Cancel = false;
                    AfterImport(this, args);
                }
            }//end if
            //更新导入批次信息
            currBatch.BatchNumber    = result.BatchNumber;
            currBatch.LastExportDate = DateTime.Now;
            this.CurrDbContext.Update <ExportBatchInfo>(currBatch);

            result.IsCancel    = false;
            result.Flag        = ImportResultFlag.Succeed;
            result.ImportCount = count;
            return(result);
        }