public string GetDBFieldStr(string prop) { EntityFields ef = EntityFieldsCache.Item(this.GetType()); string fieldName = ef.GetPropertyField(prop); return(fieldName); }
/// <summary> /// 从数据库获取下一个使用的批次号 /// </summary> /// <param name="entity"></param> /// <returns></returns> private int GetBatchNumber(EntityBase entity) { int batchNumber = 0; if (entity is IExportTable) { var tableInfoCache = EntityFieldsCache.Item(entity.GetType()); var fieldList = tableInfoCache.PropertyNames; //查询当前表最大的批次号 if (fieldList.Contains(C_Classification)) { entity[C_Classification] = ClassificationID; OQL q = OQL.From(entity) .Select().Max(((IExportTable)entity).BatchNumber, "") .Where(entity[C_Classification]) .END; var dbEntity = EntityQuery.QueryObject <IExportTable>(q, this.CurrDbContext.CurrentDataBase); batchNumber = dbEntity.BatchNumber; } else { OQL q = OQL.From(entity) .Select().Max(((IExportTable)entity).BatchNumber, "") .END; var dbEntity = EntityQuery.QueryObject <IExportTable>(q, this.CurrDbContext.CurrentDataBase); batchNumber = dbEntity.BatchNumber; } } batchNumber += 1; return(batchNumber); }
/// <summary> /// 导出实体数据到内存数据库。如果当前实体操作失败,请检查导出事件的异常参数对象。 /// </summary> /// <param name="funQ">获取导出数据的查询表达式委托方法,委托方法的参数为导出批次号;如果结果为空,导出实体全部数据</param> /// <param name="initBatchNumber">要初始化导出批次号的函数</param> public void Export(Func <int, T, OQL> funQ, Func <T, int> initBatchNumber) { Type entityType = typeof(T); try { //导出批次管理 string exportTableName = EntityFieldsCache.Item(entityType).TableName; List <ExportBatchInfo> batchList = MemDB.Get <ExportBatchInfo>(); ExportBatchInfo currBatch = batchList.FirstOrDefault(p => p.ExportTableName == exportTableName); if (currBatch == null) { currBatch = new ExportBatchInfo(); currBatch.BatchNumber = initBatchNumber == null?1: initBatchNumber(new T()); currBatch.ExportTableName = exportTableName; currBatch.LastExportDate = DateTime.Now; // batchList.Add(currBatch); MemDB.Add(currBatch); } else { currBatch.BatchNumber += 1; currBatch.LastExportDate = DateTime.Now; } MemDB.Save <ExportBatchInfo>(); //导出数据 OQL q = funQ(currBatch.BatchNumber, new T()); List <T> entityList = q != null?CurrDbContext.QueryList <T>(q) : CurrDbContext.QueryAllList <T>(); ExportEntityEventArgs <T> args = new ExportEntityEventArgs <T>(entityList, entityType, exportTableName); args.Succeed = true; args.OperationExcepiton = null; args.BatchNumber = currBatch.BatchNumber; if (OnExported != null) { OnExported(this, args); } if (!args.Cancel) { SaveEntity(entityList.ToArray(), args); } } catch (Exception ex) { ExportEntityEventArgs <T> args = new ExportEntityEventArgs <T>(null, entityType, EntityFieldsCache.Item(entityType).TableName); args.Succeed = false; args.OperationExcepiton = ex; if (OnExported != null) { OnExported(this, args); } } }
public static string ToJson(this EntityBase entity) { EntityFields ef = EntityFieldsCache.Item(entity.GetType()); JObject json = new JObject(); for (var i = 0; i < entity.PropertyNames.Length; i++) { var name = entity.PropertyNames[i]; var value = entity.PropertyValues[i]; json.Add(new JProperty(ef.GetPropertyName(name), value)); } return(json.ToString(Formatting.None, null)); }
/// <summary> /// 生成批次号为空或者为0的查询,对应于本地新增或者更新过的数据 /// </summary> /// <param name="batchNumber">批次号</param> /// <param name="entity"></param> /// <returns></returns> private OQL FilterQuery(int batchNumber, EntityBase entity) { if (entity is IExportTable) { var tableInfoCache = EntityFieldsCache.Item(entity.GetType()); var fieldList = tableInfoCache.PropertyNames; Console.WriteLine("===================导出表 [{0}] ==================", entity.GetTableName()); IExportTable ExportableEntity = entity as IExportTable; ExportableEntity.BatchNumber = batchNumber; //将数据库导出标记为0或者为空的记录,更新为当前导出标记号 //一定得按数据分类标识更新及导出 OQL updateQ = null; if (fieldList.Contains(C_Classification)) { entity[C_Classification] = ClassificationID; updateQ = OQL.From(entity) .Update(ExportableEntity.BatchNumber) .Where(cmp => cmp.EqualValue(entity[C_Classification]) & (cmp.Comparer(ExportableEntity.BatchNumber, "=", 0) | cmp.IsNull(ExportableEntity.BatchNumber)) ) .END; int count = EntityQuery.ExecuteOql(updateQ, this.CurrDbContext.CurrentDataBase); Console.WriteLine("(查询前)更新批次号 {0} 受影响的记录数 {1}", batchNumber, count); OQL q = OQL.From(entity) .Select() .Where(cmp => cmp.EqualValue(entity[C_Classification]) & cmp.EqualValue(ExportableEntity.BatchNumber)) .END; return(q); } else { updateQ = OQL.From(entity) .Update(ExportableEntity.BatchNumber) .Where(cmp => cmp.Comparer(ExportableEntity.BatchNumber, "=", 0) | cmp.IsNull(ExportableEntity.BatchNumber)) .END; int count = EntityQuery.ExecuteOql(updateQ, this.CurrDbContext.CurrentDataBase); Console.WriteLine("(查询前)更新批次号 {0} 受影响的记录数 {1}", batchNumber, count); OQL q = OQL.From(entity) .Select() .Where(cmp => cmp.EqualValue(ExportableEntity.BatchNumber)) .END; return(q); } } return(null); }
public static void FromJson(this EntityBase entity, string json) { EntityFields ef = EntityFieldsCache.Item(entity.GetType()); var obj = JObject.Parse(json, null); foreach (var p in obj.Properties()) { var name = ef.GetPropertyField(p.Name); if (!string.IsNullOrEmpty(name)) { string temp = null; int length = name.Length; for (int i = 0; i < entity.PropertyNames.Length; i++) { temp = entity.PropertyNames[i]; if (temp != null && temp.Length == length && string.Equals(temp, name, StringComparison.OrdinalIgnoreCase)) { entity.PropertyValues[i] = p.Value.Value <object>(); } } } } }
/// <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); }