using APT.Infrastructure.Core; using APT.Infrastructure.Core.Extensions; using APT.Infrastructure.Utility; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using StackExchange.Redis; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Linq.Dynamic.Core; //using Npgsql; using System.Collections; using APT.Infrastructure.Core.Refctor; using Castle.Core.Internal; using System.Collections.ObjectModel; using System.Text.RegularExpressions; using Microsoft.EntityFrameworkCore.Internal; using APT.Infrastructure.Api.Redis; using System.Collections.Concurrent; using System.Linq.Dynamic.Core; using APT.Infrastructure.Api; namespace APT.Infrastructure.EF { public class Repository : IRepository { private readonly IUnitOfWork _unitOfWork; private DataBaseType _dataBaseType = DataBaseType.SQL; private const string dbsRedisKey = "DbConn_RedisKey"; public Repository(IUnitOfWork unitOfWork) { this._unitOfWork = unitOfWork; //this._dbContext = (DbContext)unitOfWork; _dataBaseType = unitOfWork.GetDataBaseType(); } private string DesKey { get { var desKey = APT.Infrastructure.Api.ConfigurationManager.AppSettings["ConnDataKey"]; if (string.IsNullOrEmpty(desKey)) desKey = "optenergy2021001"; return desKey; } } public IUnitOfWork UnitOfWork { get { return this._unitOfWork; } } public void AddEntity(T entity, bool isSave = true) where T : MesEntityBase, new() { if (entity == null) return; List list = new List(); list.Add(entity); this.AddEntities(list, isSave); } public T AddAndGetEntity(T entity, bool isSave = true) where T : MesEntityBase, new() { if (entity == null) return null; List list = new List(); List updateSerialInfos = new List(); var type = typeof(T); if (Api.AppContext.CurrentSession.RootOrgId != null && type.GetAttribute() != null) { entity.ORG_ID = Api.AppContext.CurrentSession.RootOrgId; } list.Add(entity); var sysParams = GetSysParams(list); CheckUnique(list, null); var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); this.UpdateSerialUsedStatus(list, 0, updateSerialInfos); var userId = Api.AppContext.CurrentSession != null ? Api.AppContext.CurrentSession.UserID : null; entity.CREATE_TIME = nowTime; entity.MODIFY_TIME = nowTime; entity.CREATER_ID = userId; entity.MODIFIER_ID = userId; this.FillAcronymFieldData(list); var dbEntity = this.UnitOfWork.AddEntity(entity); this.SaveSysParams(sysParams); //DoSetIsLeaf(list, null, true); this.ExcuteUpdateSerialInfos(updateSerialInfos); if (isSave) this.UnitOfWork.SaveChanges(); SetRedis(entity, RedisHanddle.Add); return dbEntity; } public T AddAndGetEntity_noneBase(T entity) where T : class { if (entity == null) return null; var dbEntity = this.UnitOfWork.AddEntity(entity); this.UnitOfWork.SaveChanges(); return dbEntity; } public void AddEntities_noneBase(IEnumerable entities) where T : class { if (entities == null || !entities.Any()) return; this.UnitOfWork.AddEntities(entities); this.UnitOfWork.SaveChanges(); } public T GetEntity_noneBase(Expression> expressions) where T : class { var entity = this.UnitOfWork.GetEntity(expressions, null); return entity; } public List GetEntities_noneBase(Expression> expressions) where T : class { var entities = this.UnitOfWork.GetEntities(expressions, null); return entities.ToList(); } public void UpdateEntities_noneBase(IEnumerable entities) where T : class { if (entities == null || !entities.Any()) return; this.UnitOfWork.UpdateEntities(entities); this.UnitOfWork.SaveChanges(); } public void DeleteEntity_noneBase(Expression> expression) where T : class { var entities = this.UnitOfWork.GetEntities(expression, null); if (entities.Any()) { UnitOfWork.DeleteEntities(entities); this.UnitOfWork.SaveChanges(); } } #region nocomit public void AddEntityNoCommit(T entity) where T : MesEntityBase, new() { if (entity == null) return; List list = new List(); list.Add(entity); this.AddEntitiesNoCommit(list); } public void AddEntitiesNoCommit(IEnumerable entities) where T : MesEntityBase, new() { AddEntities(entities, false); } public void UpdateEntitiesNoCommit(IEnumerable entities) where T : MesEntityBase, new() { this.UpdateEntities(entities, false); } public bool UpdateEntityNoCommit(T entity, params string[] updateField) where T : MesEntityBase, new() { return this.UpdateEntity(entity, false, updateField); } public void UpdateEntitiesNoCommit(IEnumerable entities, params string[] updateField) where T : MesEntityBase, new() { this.UpdateEntities(entities, false, updateField); } //private void InitIsLeaf(IEnumerable entities, List delteIds) where T : MesEntityBase, new() //{ // var def = entities.FirstOrDefault(); // if (def != null && def is MesTreeEntityBase) // { // List addParentIds = new List(); // List deleteParentIds = new List(); // //DoSetIsLeafByUpdate(entities, addParentIds, deleteParentIds, delteIds); // deleteParentIds.RemoveAll(i => addParentIds.Contains(i)); // if (addParentIds.Any()) // { // MethodInfo methodInfo = this.GetType().GetMethod("SetParentIsLeaf", // BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static); // methodInfo.MakeGenericMethod(new Type[] { entities.FirstOrDefault().GetType() }). // Invoke(this, new object[] { addParentIds, null, true }); // } // if (deleteParentIds.Any()) // { // MethodInfo methodInfo = this.GetType().GetMethod("SetParentIsLeaf", // BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static); // methodInfo.MakeGenericMethod(new Type[] { entities.FirstOrDefault().GetType() }). // Invoke(this, new object[] { deleteParentIds, delteIds, false }); // } // } //} public void DeleteEntityNoCommit(Expression> expression) where T : MesEntityBase, new() { var entities = this.UnitOfWork.GetEntities(expression, null); if (entities.Any()) { foreach (var e in entities) { SetRedis(e, RedisHanddle.Delete); } this.DeleteEntitiesNoCommit(entities); } } public void DeleteEntityNoCommit(T entity) where T : MesEntityBase, new() { this.DeleteEntityNoCommit(i => i.ID == entity.ID); } public void DeleteEntityNoCommit(Guid id) where T : MesEntityBase, new() { var entity = this.GetEntity(id); this.DeleteEntityNoCommit(i => i.ID == id); } public void DeleteEntitiesNoCommit(IEnumerable entities) where T : MesEntityBase, new() { this.DeleteEntities(entities, false); } public void SaveEntitiesNoCommit(IEnumerable entities) where T : MesEntityBase, new() { this.SaveEntities(entities, false); } public T AddAndGetEntityNoCommit(T entity) where T : MesEntityBase, new() { return AddAndGetEntity(entity, false); } #region 指定库更新,删除 public void AddEntityByConn(T entity, string conn) where T : MesEntityBase, new() { if (entity == null) return; List list = new List(); list.Add(entity); this.AddEntitiesByConn(list, conn); } public void UpdateEntitiesByConn(IEnumerable entities, string conn) where T : MesEntityBase, new() { this.UpdateEntitiesByConn(entities, conn); } public void UpdateEntityByConn(T entity, string conn, params string[] updateField) where T : MesEntityBase, new() { List entities = new List(); entities.Add(entity); this.UpdateEntitiesByConn(entities, conn, updateField); } public void DeleteEntityByConn(Expression> expression, string conn) where T : MesEntityBase, new() { var dbconn = TenantInfoMiddleware.DesDbConn(conn); if (string.IsNullOrEmpty(dbconn)) { dbconn = ConfigurationManager.ConnectionStrings["default"]; } List entities = new List(); using (var context = new EfDbContext(dbconn)) { entities = context.GetEntities(expression, null).ToList(); } if (entities.Any()) { foreach (var e in entities) { SetRedis(e, RedisHanddle.Delete); } this.DeleteEntitiesByConn(entities, conn); } } public void DeleteEntityByConn(T entity, string conn) where T : MesEntityBase, new() { this.DeleteEntityByConn(i => i.ID == entity.ID, conn); } public void DeleteEntityByConn(Guid id, string conn) where T : MesEntityBase, new() { var entity = this.GetEntity(id); this.DeleteEntityByConn(i => i.ID == id, conn); } //统一处理 public void DeleteEntitiesByConn(IEnumerable entities, string conn) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; if (string.IsNullOrEmpty(conn)) conn = ConfigurationManager.ConnectionStrings["default"]; else conn = TenantInfoMiddleware.DesDbConn(conn); if (!string.IsNullOrEmpty(conn)) { try { DelRedis(entities); using (var context = new EfDbContext(conn)) { context.DeleteEntities(entities); context.SaveChanges(); } } catch (Exception ex) { if (ex.Message != null && ex.Message.IndexOf("约束", StringComparison.OrdinalIgnoreCase) > -1) throw new Exception("存在资料已被用,不允许执行此操作"); throw ex; } foreach (var entity in entities) SetRedis(entity, RedisHanddle.Delete); } else { if (string.IsNullOrEmpty(conn)) throw new Exception("无法获取数据库连接"); } } public void AddEntitiesByConn(IEnumerable entities, string conn) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; var userId = Api.AppContext.CurrentSession != null ? Api.AppContext.CurrentSession.UserID : null; var type = typeof(T); var rootOrgReplace = false; if (Api.AppContext.CurrentSession.RootOrgId != null && type.GetAttribute() != null) { rootOrgReplace = true; } var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); entities.ForEach(i => { i.CREATE_TIME = nowTime; i.MODIFY_TIME = nowTime; if (userId != null) { i.CREATER_ID = userId; i.MODIFIER_ID = userId; } if (rootOrgReplace) { i.ORG_ID = Api.AppContext.CurrentSession.RootOrgId; } }); this.FillAcronymFieldData(entities); List updateSerialInfos = new List(); if (string.IsNullOrEmpty(conn)) conn = ConfigurationManager.ConnectionStrings["default"]; else conn = TenantInfoMiddleware.DesDbConn(conn); if (!string.IsNullOrEmpty(conn)) { if (string.IsNullOrEmpty(conn)) throw new Exception("无法获取数据库连接"); else { using (var context = new EfDbContext(conn)) { context.AddEntities(entities); context.SaveChanges(); } } } else { throw new Exception("数据库连接不能为空"); } foreach (var entity in entities) { SetRedis(entity, RedisHanddle.Add); } DelRedisGroup(entities.FirstOrDefault().ORG_ID ?? Guid.Empty); var def = entities.FirstOrDefault(); } public void UpdateEntitiesByConn(IEnumerable entities, string conn, params string[] updateField) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; if (string.IsNullOrEmpty(conn)) conn = ConfigurationManager.ConnectionStrings["default"]; else conn = TenantInfoMiddleware.DesDbConn(conn); if (!string.IsNullOrEmpty(conn)) { if (string.IsNullOrEmpty(conn)) throw new Exception("无法获取数据库连接"); else { //数据处理 var deleteEntities = entities.Where(t => t.IS_DELETED).ToList(); var updateEntities = entities.Where(t => !t.IS_DELETED).ToList(); //更新别名 this.FillAcronymFieldData(updateEntities, updateField); //数据处理 var type = typeof(T); var rootOrgReplace = false; if (Api.AppContext.CurrentSession.RootOrgId != null && type.GetAttribute() != null) { rootOrgReplace = true; } if (updateField != null && updateField.Any()) { updateField = updateField.Append("ID").ToArray(); } bool isRedis = false; var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass != null) { isRedis = true; } Guid? currentUserId = null; if (Api.AppContext.CurrentSession != null && !string.IsNullOrEmpty(Api.AppContext.CurrentSession.UserId)) currentUserId = new Guid(Api.AppContext.CurrentSession.UserId); var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); foreach (var i in updateEntities) { i.MODIFY_TIME = nowTime; if (rootOrgReplace) { i.ORG_ID = Api.AppContext.CurrentSession.RootOrgId; } if (currentUserId != null) { i.MODIFIER_ID = currentUserId; } } //redis数据删除 if (isRedis) { DelRedis(entities); } using (var context = new EfDbContext(conn)) { CheckRowVersion(entities, context); context.UpdateEntities(updateEntities, updateField); context.DeleteEntities(deleteEntities); context.SaveChanges(); } } } else { throw new Exception("数据库连接不能为空"); } } public void AddEntityByTenant(T entity, string tenant) where T : MesEntityBase, new() { if (entity == null) return; List list = new List(); list.Add(entity); this.AddEntitiesByTenant(list, tenant); } public void UpdateEntitiesByTenant(IEnumerable entities, string tenant) where T : MesEntityBase, new() { this.UpdateEntitiesByTenant(entities, tenant); } public void UpdateEntityByTenant(T entity, string tenant, params string[] updateField) where T : MesEntityBase, new() { List entities = new List(); entities.Add(entity); this.UpdateEntitiesByTenant(entities, tenant, updateField); } public void DeleteEntityByTenant(Expression> expression, string tenant) where T : MesEntityBase, new() { var dbconn = ""; if (string.IsNullOrEmpty(tenant)) dbconn = ConfigurationManager.ConnectionStrings["default"]; else dbconn = TenantInfoMiddleware.GetDbConn(tenant); List entities = new List(); using (var context = new EfDbContext(dbconn)) { entities = context.GetEntities(expression, null).ToList(); } if (entities.Any()) { foreach (var e in entities) { SetRedis(e, RedisHanddle.Delete); } this.DeleteEntitiesByTenant(entities, tenant); } } public void DeleteEntityByTenant(T entity, string tenant) where T : MesEntityBase, new() { this.DeleteEntityByConn(i => i.ID == entity.ID, tenant); } public void DeleteEntityByTenant(Guid id, string tenant) where T : MesEntityBase, new() { var entity = this.GetEntity(id); this.DeleteEntityByConn(i => i.ID == id, tenant); } //统一处理 public void DeleteEntitiesByTenant(IEnumerable entities, string tenant) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; var dbconn = ""; if (string.IsNullOrEmpty(tenant)) dbconn = ConfigurationManager.ConnectionStrings["default"]; else dbconn = TenantInfoMiddleware.GetDbConn(tenant); if (!string.IsNullOrEmpty(tenant)) { if (string.IsNullOrEmpty(dbconn)) throw new Exception("无法获取数据库连接"); else { try { DelRedis(entities); using (var context = new EfDbContext(dbconn)) { context.DeleteEntities(entities); context.SaveChanges(); } } catch (Exception ex) { if (ex.Message != null && ex.Message.IndexOf("约束", StringComparison.OrdinalIgnoreCase) > -1) throw new Exception("存在资料已被用,不允许执行此操作"); throw ex; } foreach (var entity in entities) SetRedis(entity, RedisHanddle.Delete); } } else { throw new Exception("数据库连接不能为空"); } } public void AddEntitiesByTenant(IEnumerable entities, string tenant) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; var userId = Api.AppContext.CurrentSession != null ? Api.AppContext.CurrentSession.UserID : null; var type = typeof(T); var rootOrgReplace = false; if (Api.AppContext.CurrentSession.RootOrgId != null && type.GetAttribute() != null) { rootOrgReplace = true; } var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); entities.ForEach(i => { i.CREATE_TIME = nowTime; i.MODIFY_TIME = nowTime; if (userId != null) { i.CREATER_ID = userId; i.MODIFIER_ID = userId; } if (rootOrgReplace) { i.ORG_ID = Api.AppContext.CurrentSession.RootOrgId; } }); this.FillAcronymFieldData(entities); List updateSerialInfos = new List(); var dbconn = ""; if (string.IsNullOrEmpty(tenant)) dbconn = ConfigurationManager.ConnectionStrings["default"]; else dbconn = TenantInfoMiddleware.GetDbConn(tenant); if (!string.IsNullOrEmpty(tenant)) { if (string.IsNullOrEmpty(dbconn)) throw new Exception("无法获取数据库连接"); else { using (var context = new EfDbContext(dbconn)) { context.AddEntities(entities); context.SaveChanges(); } } } else { throw new Exception("数据库连接不能为空"); } foreach (var entity in entities) { SetRedis(entity, RedisHanddle.Add); } DelRedisGroup(entities.FirstOrDefault().ORG_ID ?? Guid.Empty); var def = entities.FirstOrDefault(); } public void UpdateEntitiesByTenant(IEnumerable entities, string tenant, params string[] updateField) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; var dbconn = ""; if (string.IsNullOrEmpty(tenant)) dbconn = ConfigurationManager.ConnectionStrings["default"]; else dbconn = TenantInfoMiddleware.GetDbConn(tenant); if (!string.IsNullOrEmpty(tenant)) { if (string.IsNullOrEmpty(dbconn)) throw new Exception("无法获取数据库连接"); else { //数据处理 var deleteEntities = entities.Where(t => t.IS_DELETED).ToList(); var updateEntities = entities.Where(t => !t.IS_DELETED).ToList(); //更新别名 this.FillAcronymFieldData(updateEntities, updateField); //数据处理 var type = typeof(T); var rootOrgReplace = false; if (Api.AppContext.CurrentSession.RootOrgId != null && type.GetAttribute() != null) { rootOrgReplace = true; } if (updateField != null && updateField.Any()) { updateField = updateField.Append("ID").ToArray(); } bool isRedis = false; var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass != null) { isRedis = true; } Guid? currentUserId = null; if (Api.AppContext.CurrentSession != null && !string.IsNullOrEmpty(Api.AppContext.CurrentSession.UserId)) currentUserId = new Guid(Api.AppContext.CurrentSession.UserId); var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); foreach (var i in updateEntities) { i.MODIFY_TIME = nowTime; if (rootOrgReplace) { i.ORG_ID = Api.AppContext.CurrentSession.RootOrgId; } if (currentUserId != null) { i.MODIFIER_ID = currentUserId; } } //redis数据删除 if (isRedis) { DelRedis(entities); } using (var context = new EfDbContext(dbconn)) { CheckRowVersion(entities, context); context.UpdateEntities(updateEntities, updateField); context.DeleteEntities(deleteEntities); context.SaveChanges(); } } } else { throw new Exception("数据库连接不能为空"); } } #endregion #endregion public void AddEntities(IEnumerable entities, bool isSave = true) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; this.CheckUnique(entities, null); var userId = Api.AppContext.CurrentSession != null ? Api.AppContext.CurrentSession.UserID : null; var type = typeof(T); var rootOrgReplace = false; if (Api.AppContext.CurrentSession.RootOrgId != null && type.GetAttribute() != null) { rootOrgReplace = true; } var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); entities.ForEach(i => { i.CREATE_TIME = nowTime; i.MODIFY_TIME = nowTime; if (userId != null) { i.CREATER_ID = userId; i.MODIFIER_ID = userId; } if (rootOrgReplace) { i.ORG_ID = Api.AppContext.CurrentSession.RootOrgId; } }); this.FillAcronymFieldData(entities); List updateSerialInfos = new List(); this.UpdateSerialUsedStatus(entities, 0, updateSerialInfos); var sysParams = GetSysParams(entities); this.UnitOfWork.AddEntities(entities); foreach (var entity in entities) { SetRedis(entity, RedisHanddle.Add); } DelRedisGroup(entities.FirstOrDefault().ORG_ID ?? Guid.Empty); SaveSysParams(sysParams); //DoSetIsLeaf(entities, null, true); var def = entities.FirstOrDefault(); this.ExcuteUpdateSerialInfos(updateSerialInfos); if (isSave) { this.UnitOfWork.SaveChanges(); } } public void DeleteEntity(T entity, bool isSave = true) where T : MesEntityBase, new() { this.DeleteEntity(entity.ID, isSave); } public void DeleteEntity(Guid key, bool isSave = true) where T : MesEntityBase, new() { var entity = this.GetEntity(key); this.DeleteEntity(t => t.ID == key, isSave); } public void DeleteEntity(Expression> predicate, bool isSave = true) where T : MesEntityBase, new() { var entities = this.UnitOfWork.GetEntities(predicate, null); if (entities.Any()) { this.DeleteEntities(entities, isSave); } } public void DeleteEntities(IEnumerable entities, bool isSave = true) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; List updateSerialInfos = new List(); var sysParams = GetSysParams(entities, true); this.UpdateSerialUsedStatus(entities, 2, updateSerialInfos); this.UnitOfWork.DeleteEntities(entities); //DoSetIsLeaf(entities, entities.Select(i => i.ID).ToList(), false); this.SaveSysParams(sysParams); this.ExcuteUpdateSerialInfos(updateSerialInfos); DelRedis(entities); try { if (isSave) { this.UnitOfWork.SaveChanges(); } } catch (Exception ex) { if (ex.Message != null && ex.Message.IndexOf("约束", StringComparison.OrdinalIgnoreCase) > -1) throw new Exception("存在资料已被用,不允许执行此操作"); throw ex; } foreach (var entity in entities) SetRedis(entity, RedisHanddle.Delete); } public bool UpdateEntity(T entity, bool isSave = true, params string[] updateField) where T : MesEntityBase, new() { if (entity == null) return false; if (entity.IS_DELETED) this.DeleteEntity(entity); else { List entities = new List(); entities.Add(entity); if (updateField == null || !updateField.Any()) this.SaveEntities(entities, isSave); else { this.UpdateEntities(entities, isSave, updateField); } } return true; } public void UpdateEntities(IEnumerable entities, bool isSave = true, params string[] updateField) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; CheckRowVersion(entities); List updateSerialInfos = new List(); var sysParams = GetSysParams(entities); var deleteEntities = entities.Where(t => t.IS_DELETED).ToList(); var updateEntities = entities.Where(t => !t.IS_DELETED).ToList(); CheckUnique(entities, deleteEntities); //List addParentIds = new List(); //List deleteParentIds = new List(); //List deleteIds = new List(); //DoSetIsLeafByUpdate(updateEntities, addParentIds, deleteParentIds, deleteIds); //更新别名 this.FillAcronymFieldData(updateEntities, updateField); //数据处理 var type = typeof(T); var rootOrgReplace = false; if (Api.AppContext.CurrentSession.RootOrgId != null && type.GetAttribute() != null) { rootOrgReplace = true; } if (updateField != null && updateField.Any()) { updateField = updateField.Append("ID").ToArray(); } bool isRedis = false; var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass != null) { isRedis = true; } Guid? currentUserId = null; if (Api.AppContext.CurrentSession != null && !string.IsNullOrEmpty(Api.AppContext.CurrentSession.UserId)) currentUserId = new Guid(Api.AppContext.CurrentSession.UserId); var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); foreach (var i in updateEntities) { i.MODIFY_TIME = nowTime; if (rootOrgReplace) { i.ORG_ID = Api.AppContext.CurrentSession.RootOrgId; } if (currentUserId != null) { i.MODIFIER_ID = currentUserId; } } if (isRedis) { //CsRedisManager.GetClient().Del(updateEntities.Select(i => i.ID.ToString()).ToArray()); DelRedis(entities); } this.UpdateSerialUsedStatus(updateEntities, 1, updateSerialInfos); this.UpdateSerialUsedStatus(deleteEntities, 2, updateSerialInfos); this.UnitOfWork.UpdateEntities(updateEntities, updateField); this.UnitOfWork.DeleteEntities(deleteEntities); // //deleteParentIds.RemoveAll(i => addParentIds.Contains(i)); //if (addParentIds.Any()) //{ // MethodInfo methodInfo = this.GetType().GetMethod("SetParentIsLeaf", // BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static); // methodInfo.MakeGenericMethod(new Type[] { entities.FirstOrDefault().GetType() }). // Invoke(this, new object[] { addParentIds, deleteIds, true }); //} //if (deleteParentIds.Any()) //{ // MethodInfo methodInfo = this.GetType().GetMethod("SetParentIsLeaf", // BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static); // methodInfo.MakeGenericMethod(new Type[] { entities.FirstOrDefault().GetType() }). // Invoke(this, new object[] { deleteParentIds, deleteIds, false }); //} this.SaveSysParams(sysParams); this.ExcuteUpdateSerialInfos(updateSerialInfos); if (isSave) this.UnitOfWork.SaveChanges(); } public void SaveEntities(IEnumerable entities, bool isSave = true) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; var type = typeof(T); var rootOrgReplace = false; if (Api.AppContext.CurrentSession.RootOrgId != null && type.GetAttribute() != null) { rootOrgReplace = true; } CheckRowVersion(entities); var sysParams = GetSysParams(entities); var deleteEntities = entities.Where(t => t.IS_DELETED).ToList(); var saveEntities = entities.Where(t => !t.IS_DELETED).ToList(); List updateEntities = new List(); List addEntities = new List(); List deleteIds = new List(); List updateSerialInfos = new List(); var def = entities.FirstOrDefault(); List addParentIds = new List(); List deleteParentIds = new List(); if (deleteEntities.Any()) { this.UpdateSerialUsedStatus(deleteEntities, 2, updateSerialInfos); var delIds = deleteEntities.Select(i => i.ID).ToArray(); var dbDelEntities = this.UnitOfWork.GetEntities(t => delIds.Contains(t.ID), null, true).ToList(); this.UnitOfWork.DeleteEntities(dbDelEntities); //if (def != null && def is MesTreeEntityBase) //{ // var deleteTreeEntitis = deleteEntities as List; // var deletePIds = deleteTreeEntitis.Select(i => i.PARENT_ID ?? Guid.Empty).Distinct().ToList(); // deleteIds = deleteTreeEntitis.Select(i => i.ID).Distinct().ToList(); // deleteParentIds.AddRange(deletePIds); //} } if (saveEntities.Any()) { this.CheckUnique(saveEntities, deleteEntities); //DoSetIsLeafByUpdate(saveEntities, addParentIds, deleteParentIds, deleteIds); var ids = saveEntities.Select(t => t.ID).ToList(); List dbUpdateEntities = this.UnitOfWork.GetEntities(t => ids.Contains(t.ID), null, true).ToList(); var dbContext = (DbContext)this.UnitOfWork; var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); foreach (var entity in saveEntities) { if (rootOrgReplace) { entity.ORG_ID = Api.AppContext.CurrentSession.RootOrgId; } var dbEntity = dbUpdateEntities.FirstOrDefault(t => t.ID.ToString() == entity.ID.ToString()); if (dbEntity != null) { entity.MODIFY_TIME = nowTime; if (Api.AppContext.CurrentSession != null && !string.IsNullOrEmpty(Api.AppContext.CurrentSession.UserId)) { entity.MODIFIER_ID = new Guid(Api.AppContext.CurrentSession.UserId); } var oldContexEntity = dbContext.Entry(dbEntity); oldContexEntity.CurrentValues.SetValues(entity); updateEntities.Add(dbEntity); //SetRedis(entity, RedisHanddle.Update); } else { entity.MODIFY_TIME = nowTime; entity.CREATE_TIME = nowTime; if (Api.AppContext.CurrentSession != null && !string.IsNullOrEmpty(Api.AppContext.CurrentSession.UserId)) { entity.MODIFIER_ID = new Guid(Api.AppContext.CurrentSession.UserId); entity.CREATER_ID = new Guid(Api.AppContext.CurrentSession.UserId); } addEntities.Add(entity); //SetRedis(entity, RedisHanddle.Add); } deleteParentIds.RemoveAll(i => addParentIds.Contains(i)); } DelRedis(entities); this.FillAcronymFieldData(saveEntities); this.UnitOfWork.UpdateEntities(updateEntities); this.UnitOfWork.AddEntities(addEntities); this.UpdateSerialUsedStatus(addEntities, 0, updateSerialInfos); this.UpdateSerialUsedStatus(updateEntities, 1, updateSerialInfos); } this.SaveSysParams(sysParams); this.ExcuteUpdateSerialInfos(updateSerialInfos); try { if (isSave) { this.UnitOfWork.SaveChanges(); } } catch (Exception ex) { //if (ex.Message != null && ex.Message.IndexOf("约束", StringComparison.OrdinalIgnoreCase) > -1) // throw new Exception("存在资料已被用,不允许执行此操作"); throw ex; } } public T GetEntity(Guid id, params string[] paths) where T : MesEntityBase, new() { return this.GetEntity(t => t.ID == id, null, paths); } public T GetEntity(Expression> expression, BaseFilter filter, params string[] paths) where T : MesEntityBase, new() { return this.GetEntity(expression, filter, (!filter?.IsNoTranking) ?? true, paths); } public T GetEntity(Expression> expression, BaseFilter filter, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { if (filter != null && Api.AppContext.CurrentSession.DataRule != null && !filter.IgnoreDataRule && !filter.DataRule.Any()) { filter.DataRule = Api.AppContext.CurrentSession.DataRule; } string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, filter, paths, null, out orgExpression, out realPaths, out realOrders, false); List selectFields = new List(); T ret = null; if (filter != null && filter.SelectField != null && filter.SelectField.Any()) { selectFields = filter.SelectField.ToList(); AppendSelectedField(selectFields); } //多库联合查询 if (filter != null) { if (filter.IsMultipleDb) { var conns = GetAllDbConns();//查询redis里面的数据库连接 foreach (var conn in conns) { using (var context = new EfDbContext(conn)) { ret = context.GetEntity(exp, realOrders, selectFields.ToArray(), isTracking, realPaths); if (ret != null) { var dbConn = TenantInfoMiddleware.EnDbConn(conn); ret.DbConn = dbConn; break; } } } } else if (filter.IsSpecifyDb) { string enConn = GetSpecifyDb(filter); using (var context = new EfDbContext(enConn)) { ret = context.GetEntity(exp, realOrders, selectFields.ToArray(), isTracking, realPaths); if (ret != null) { ret.DbConn = filter.SpecifyDbConn; } } } else { ret = this.UnitOfWork.GetEntity(exp, realOrders, selectFields.ToArray(), isTracking, realPaths); } } else { ret = this.UnitOfWork.GetEntity(exp, realOrders, selectFields.ToArray(), isTracking, realPaths); } //导航属性 if (ret != null) { List list = new List(); list.Add(ret); this.FillGetEntitySysParam(list, filter, paths); if (selectFields != null && selectFields.Any()) { realPaths = SelectFieldInclude(realPaths, selectFields); NavigationDeal(realPaths, list, selectFields.ToArray(), filter.DataRule.ToArray(), filter.OrgRule, filter.OrgId, filter.IgnoreOrgRule, filter.IgnoreDataRule, isTracking, filter.IsMultipleDb, filter.IsSpecifyDb, filter.SpecifyDbConn); } } return ret; } public IEnumerable GetEntities(Expression> expression, BaseFilter filter, params string[] paths) where T : MesEntityBase, new() { return this.GetEntities(expression, filter, (!filter?.IsNoTranking) ?? true, paths); } private IEnumerable GetEntities(BaseFilter filter) where T : MesEntityBase, new() { return this.GetEntities(null, filter); } public IEnumerable GetEntities(Expression> expression, BaseFilter filter, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, filter, paths, null, out orgExpression, out realPaths, out realOrders, false); List selectFields = new List(); if (filter != null && Api.AppContext.CurrentSession.DataRule != null && !filter.IgnoreDataRule && !filter.DataRule.Any()) { filter.DataRule = Api.AppContext.CurrentSession.DataRule; } if (filter != null && filter.SelectField != null && filter.SelectField.Any()) { selectFields = filter.SelectField.ToList(); AppendSelectedField(selectFields); } //支持多库联合查询 var entities = new List(); if (filter != null) { if (filter.IsMultipleDb) { var conns = GetAllDbConns();//查询redis里面的数据库连接 foreach (var conn in conns) { using (var context = new EfDbContext(conn)) { var contextEntities = context.GetEntities(exp, selectFields.ToArray(), isTracking, realPaths); if (contextEntities.Any()) { var dbConn = TenantInfoMiddleware.EnDbConn(conn); contextEntities.ForEach(i => i.DbConn = dbConn); entities.AddRange(contextEntities); } } } } else if (filter.IsSpecifyDb) { string enConn = GetSpecifyDb(filter); using (var context = new EfDbContext(enConn)) { entities = context.GetEntities(exp, selectFields.ToArray(), isTracking, realPaths).ToList(); } } else { entities = this.UnitOfWork.GetEntities(exp, selectFields.ToArray(), isTracking, realPaths).ToList(); } } else { entities = this.UnitOfWork.GetEntities(exp, selectFields.ToArray(), isTracking, realPaths).ToList(); } if (entities != null && entities.Any()) this.FillGetEntitySysParam(entities, filter, paths); //导航属性处理 if (selectFields != null && selectFields.Any()) { realPaths = SelectFieldInclude(realPaths, selectFields); NavigationDeal(realPaths, entities, selectFields.ToArray(), filter.DataRule.ToArray(), filter.OrgRule, filter.OrgId, filter.IgnoreOrgRule, filter.IgnoreDataRule, isTracking, filter.IsMultipleDb, filter.IsSpecifyDb, filter.SpecifyDbConn); } return entities; } private static string[] SelectFieldInclude(string[] realPaths, List selectFields) { List tmp = new List(); if (realPaths != null) { tmp = new List(realPaths); } foreach (var field in selectFields) { if (field.IndexOf(".") > 0) { var index = field.LastIndexOf("."); var includPath = field.Substring(0, index); if (!tmp.Contains(includPath)) { tmp.Add(includPath); } } } realPaths = tmp.ToArray(); return realPaths; } public IEnumerable GetOrderEntities(Expression> expression, BaseFilter filter, params string[] paths) where T : MesEntityBase, new() { return this.GetOrderEntities(expression, filter, null, (!filter?.IsNoTranking) ?? true, paths); } public IEnumerable GetTree(string id, bool containCurrent = true, BaseFilter filter = null, params string[] paths) where T : TreeEntityBase, new() { var gid = new Guid(id); List guidList = new List(); List allList = new List(); guidList.Add(gid); if (containCurrent) { if (filter != null) { if (filter.IsMultipleDb) { var conns = GetAllDbConns();//查询redis里面的数据库连接 foreach (var conn in conns) { using (var context = new EfDbContext(conn)) { var top = context.GetEntity(i => i.ID == gid, filter.SelectField?.ToArray(), paths); if (top != null) { allList.Add(top); var dbConn = TenantInfoMiddleware.EnDbConn(conn); top.DbConn = dbConn; break; } } } } else if (filter.IsSpecifyDb) { string enConn = GetSpecifyDb(filter); using (var context = new EfDbContext(enConn)) { var top = context.GetEntity(i => i.ID == gid, filter.SelectField?.ToArray(), paths); if (top != null) { allList.Add(top); } } } else { var top = this.GetEntity(gid, paths); if (top != null) allList.Add(top); } } else { var top = this.GetEntity(gid, paths); if (top != null) allList.Add(top); } } GetChildEntity(paths, filter, guidList, allList); return allList; } private void AppendSelectedField(List selectFields) { if (selectFields != null && selectFields.Any()) { var type = typeof(T); var keys = this.UnitOfWork.GetModelForeignKey(type.Name); foreach (var fkey in keys) { if (fkey.ForeignNavName == null || selectFields.Contains(fkey.ForeignFieldName) || !selectFields.Any(i => i.Contains(fkey.ForeignNavName))) continue; var prop = type.GetProperty(fkey.ForeignNavName); if (prop != null && !typeof(System.Collections.IEnumerable).IsAssignableFrom(prop.PropertyType)) { selectFields.Add(fkey.ForeignFieldName); } } if (!selectFields.Contains("ID")) { selectFields.Add("ID"); } } } private void GetChildEntity(string[] paths, BaseFilter filter, List guidList, List allList) where T : TreeEntityBase, new() { var top = new List(); if (filter != null) { if (filter.IsMultipleDb) { var conns = GetAllDbConns();//查询redis里面的数据库连接 foreach (var conn in conns) { using (var context = new EfDbContext(conn)) { var contexEntities = context.GetEntities(i => guidList.Contains(i.PARENT_ID ?? Guid.Empty), filter.SelectField?.ToArray(), paths).ToList(); if (contexEntities != null && contexEntities.Any()) { var dbConn = TenantInfoMiddleware.EnDbConn(conn); contexEntities.ForEach(i => i.DbConn = dbConn); top.AddRange(contexEntities); } } } } else if (filter.IsSpecifyDb) { string enConn = GetSpecifyDb(filter); using (var context = new EfDbContext(enConn)) { var contexEntities = context.GetEntities(i => guidList.Contains(i.PARENT_ID ?? Guid.Empty), filter.SelectField?.ToArray(), paths).ToList(); if (contexEntities != null && contexEntities.Any()) { top.AddRange(contexEntities); } } } else { top = this.GetEntities(i => guidList.Contains(i.PARENT_ID ?? Guid.Empty), new BaseFilter(), paths).ToList(); } } else { top = this.GetEntities(i => guidList.Contains(i.PARENT_ID ?? Guid.Empty), new BaseFilter(), paths).ToList(); ; } if (top.Any()) { allList.AddRange(top); var childGuidList = top.Select(i => i.ID).ToList(); GetChildEntity(paths, filter, childGuidList, allList); } } public IEnumerable> GetTreeOrderEntities(Expression> expression, BaseFilter filter, bool isTracking = true, params string[] paths) where T : TreeEntityBase, new() { if (filter != null && Api.AppContext.CurrentSession.DataRule != null && !filter.IgnoreDataRule && !filter.DataRule.Any()) { filter.DataRule = Api.AppContext.CurrentSession.DataRule; } string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, filter, paths, null, out orgExpression, out realPaths, out realOrders, false); List resultList = null; List> data = new List>(); if (filter != null) { if (filter.IsMultipleDb) { var conns = GetAllDbConns();//查询redis里面的数据库连接 foreach (var conn in conns) { using (var context = new EfDbContext(conn)) { var contextEntities = context.GetTreeOrderEntities(exp, filter, orgExpression, out resultList, isTracking, realPaths); if (contextEntities.Any()) { var dbConn = TenantInfoMiddleware.EnDbConn(conn); contextEntities.ForEach(i => i.Node.DbConn = dbConn); data.AddRange(contextEntities); } } } } else if (filter.IsSpecifyDb) { string enConn = GetSpecifyDb(filter); using (var context = new EfDbContext(enConn)) { var contexEntities = context.GetTreeOrderEntities(exp, filter, orgExpression, out resultList, isTracking, realPaths); if (contexEntities != null && contexEntities.Any()) { data.AddRange(contexEntities); } } } else { data = this.UnitOfWork.GetTreeOrderEntities(exp, filter, orgExpression, out resultList, isTracking, realPaths).ToList(); } } else { data = this.UnitOfWork.GetTreeOrderEntities(exp, filter, orgExpression, out resultList, isTracking, realPaths).ToList(); } if (filter != null && filter.SelectField.Any()) { realPaths = SelectFieldInclude(realPaths, filter.SelectField.ToList()); NavigationDeal(realPaths, resultList, filter.SelectField.ToArray(), filter.DataRule.ToArray(), filter.OrgRule, filter.OrgId, filter.IgnoreOrgRule, filter.IgnoreDataRule, isTracking, filter.IsMultipleDb, filter.IsSpecifyDb, filter.SpecifyDbConn); } return data; } private void InitTreeNode(List> dataLists, TreeNode parentNode) where T : TreeEntityBase, new() { if (dataLists.Count <= parentNode.Level) return; List levalData = new List(); if (parentNode.Node != null) { levalData = dataLists[parentNode.Level].Where(i => i.PARENT_ID == parentNode.Node.ID).ToList(); } else { levalData = dataLists[parentNode.Level].ToList(); } IList childData = new List(); if (parentNode.Level < dataLists.Count - 1) { childData = dataLists[parentNode.Level + 1]; } //构造node节点 foreach (var d in levalData) { TreeNode node = new Core.TreeNode(); parentNode.Children.Add(node); node.Node = d; node.Level = parentNode.Level + 1; node.IsLeaf = d.IS_LEAF; node.Children = new List>(); if (childData.Any(i => i.PARENT_ID == d.ID)) { node.IsLeaf = false; InitTreeNode(dataLists, node); } } } /// /// 分级构造树的数据 /// /// /// /// /// /// /// private void InitDownTree(Expression> expression, BaseFilter filter, string[] paths, IList data, List> dataLists) where T : TreeEntityBase, new() { dataLists.Add(data); if (dataLists.Count < filter.Level || filter.Level == -1) { var dataIds = dataLists[dataLists.Count - 1].Select(i => i.ID).ToList(); var secExpression = expression.And(i => dataIds.Contains(i.PARENT_ID ?? Guid.Empty)); var childData = this.GetOrderEntities(secExpression, filter, null, (!filter?.IsNoTranking) ?? true, paths).ToList(); if (childData.Any()) { InitDownTree(expression, filter, paths, childData, dataLists); } } } public IEnumerable GetOrderEntities(Expression> expression, BaseFilter filter, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { return this.GetOrderEntities(expression, filter, null, isTracking, paths); } public IEnumerable GetOrderEntities(Expression> expression, BaseFilter filter, Dictionary orders, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { return this.GetOrderEntities(expression, filter, orders, null, isTracking, paths); } public IEnumerable GetOrderEntities(Expression> expression, BaseFilter filter, Dictionary orders, Action> orderBy, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, filter, paths, orders, out orgExpression, out realPaths, out realOrders, false); List selectFields = new List(); if (filter != null && Api.AppContext.CurrentSession.DataRule != null && !filter.IgnoreDataRule && !filter.DataRule.Any()) { filter.DataRule = Api.AppContext.CurrentSession.DataRule; } if (filter != null && filter.SelectField != null && filter.SelectField.Any()) { selectFields = filter.SelectField.ToList(); AppendSelectedField(selectFields); } //支持多库联合查询 var entities = new List(); if (filter != null) { if (filter.IsMultipleDb) { var conns = GetAllDbConns();//查询redis里面的数据库连接 foreach (var conn in conns) { using (var context = new EfDbContext(conn)) { var contextEntities = context.GetOrderEntities(exp, realOrders, orderBy, filter == null ? null : selectFields.ToArray(), isTracking, realPaths); if (contextEntities.Any()) { var dbConn = TenantInfoMiddleware.EnDbConn(conn); contextEntities.ForEach(i => i.DbConn = dbConn); entities.AddRange(contextEntities); } } } } else if (filter.IsSpecifyDb) { string enConn = GetSpecifyDb(filter); using (var context = new EfDbContext(enConn)) { entities = context.GetOrderEntities(exp, realOrders, orderBy, filter == null ? null : selectFields.ToArray(), isTracking, realPaths).ToList(); } } else { entities = this.UnitOfWork.GetOrderEntities(exp, realOrders, orderBy, filter == null ? null : selectFields.ToArray(), isTracking, realPaths).ToList(); } } else { entities = this.UnitOfWork.GetOrderEntities(exp, realOrders, orderBy, filter == null ? null : selectFields.ToArray(), isTracking, realPaths).ToList(); } //导航属性 if (filter != null && filter.SelectField.ToArray().Any()) { realPaths = SelectFieldInclude(realPaths, filter.SelectField.ToList()); NavigationDeal(realPaths, entities.ToList(), filter.SelectField.ToArray(), filter.DataRule.ToArray(), filter.OrgRule, filter.OrgId, filter.IgnoreOrgRule, filter.IgnoreDataRule, isTracking, filter.IsMultipleDb, filter.IsSpecifyDb, filter.SpecifyDbConn); } if (entities != null && entities.Any()) this.FillGetEntitySysParam(entities, filter, paths); return entities; } private string GetSpecifyDb(BaseFilter filter) { var enConn = ""; if (!string.IsNullOrEmpty(filter.SpecifyTenant)) { enConn = TenantInfoMiddleware.GetDbConn(filter.SpecifyTenant); } else if (!string.IsNullOrEmpty(filter.SpecifyDbConn)) { enConn = EncryptHelper.AesDecrypt(filter.SpecifyDbConn, DesKey); } else { enConn = ConfigurationManager.ConnectionStrings["default"]; } return enConn; } public PagedResultDto GetPageEntities(Expression> expression, BasePageFilter pageFilter, params string[] paths) where T : MesEntityBase, new() { return this.GetPageEntities(expression, pageFilter, paths); } public PagedResultDto GetOrderPageEntities(Expression> expression, BasePageFilter pageFilter, params string[] paths) where T : MesEntityBase, new() { return this.GetOrderPageEntities(expression, pageFilter, 0, 0, paths); } public PagedResultDto GetOrderPageEntities(Expression> expression, BasePageFilter pageFilter, int pageSize, int startIndex, params string[] paths) where T : MesEntityBase, new() { return this.GetOrderPageEntities(expression, pageFilter, pageSize, startIndex, (!pageFilter?.IsNoTranking) ?? true, paths); } public PagedResultDto GetMultipleDbPageEntities(Expression> expression, BasePageFilter pageFilter, params string[] paths) where T : MesEntityBase, new() { if (pageFilter == null) throw new Exception("Filter参数不能为空"); if (expression == null) expression = t => true; pageFilter.IsMultipleDb = true; //expression = expression.And(i => i.CREATE_TIME > pageFilter.StartTime); return this.GetOrderPageEntities(expression, pageFilter, null, pageFilter.Limit, pageFilter.Start, null, (!pageFilter?.IsNoTranking) ?? true, paths); } public PagedResultDto GetOrderPageEntities(Expression> expression, BasePageFilter pageFilter, int pageSize, int startIndex, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { return this.GetOrderPageEntities(expression, pageFilter, null, pageSize, startIndex, isTracking, paths); } public PagedResultDto GetOrderPageEntities(Expression> expression, BasePageFilter pageFilter, Dictionary orders, int pageSize, int startIndex, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { return this.GetOrderPageEntities(expression, pageFilter, orders, pageSize, startIndex, null, isTracking, paths); } public PagedResultDto GetOrderPageEntities(Expression> expression, BasePageFilter pageFilter, Dictionary orders, int pageSize, int startIndex, Action> orderBy, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { PagedResultDto ret = new PagedResultDto(); //查询所有数据 if (pageFilter != null && pageFilter.IsAllLoad) { var data = this.GetOrderEntities(expression, pageFilter, orders, isTracking, paths).ToList(); ret.Items = data; ret.TotalCount = data.Count; return ret; } if (pageFilter != null && !pageFilter.IgnoreDataRule && !pageFilter.DataRule.Any()) { pageFilter.DataRule = Api.AppContext.CurrentSession.DataRule; } //分页查询 string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, pageFilter, paths, orders, out orgExpression, out realPaths, out realOrders, false); int tempPageSize = 0; int tempStartIndex = 0; List selectFields = new List(); //分页参数 if (pageSize != 0) { tempPageSize = pageSize; tempStartIndex = startIndex; } else if (pageFilter != null) { tempStartIndex = pageFilter.Start; tempPageSize = pageFilter.Limit; } //查询字段处理 if (pageFilter != null && pageFilter.SelectField != null && pageFilter.SelectField.Any()) { selectFields = pageFilter.SelectField.ToList(); AppendSelectedField(selectFields); } //支持多库联合查询 ret = MutilDbOrderPaged(pageFilter, pageSize, startIndex, orderBy, isTracking, realPaths, realOrders, exp, tempPageSize, tempStartIndex, selectFields); //字段查询导航处理 if (selectFields.Any()) { //导航属性 realPaths = SelectFieldInclude(realPaths, pageFilter.SelectField.ToList()); NavigationDeal(realPaths, ret.Items, pageFilter.SelectField.ToArray(), pageFilter.DataRule.ToArray(), pageFilter.OrgRule, pageFilter.OrgId, pageFilter.IgnoreOrgRule, pageFilter.IgnoreDataRule, isTracking, pageFilter.IsMultipleDb, pageFilter.IsSpecifyDb, pageFilter.SpecifyDbConn); } //系统属性 if (ret != null && ret.Items.Any()) this.FillGetEntitySysParam(ret.Items, pageFilter, paths); return ret; } private PagedResultDto MutilDbOrderPaged(BasePageFilter pageFilter, int pageSize, int startIndex, Action> orderBy, bool isTracking, string[] realPaths, Dictionary realOrders, Expression> exp, int tempPageSize, int tempStartIndex, List selectFields) where T : MesEntityBase, new() { PagedResultDto ret = new PagedResultDto(); var entities = new List(); var totalCount = 0; if (pageFilter != null) { if (pageFilter.IsMultipleDb) { var conns = GetAllDbConns();//查询redis里面的数据库连接 var dbCount = conns.Count; if (dbCount == 0) return ret; //Action> multipleOrderBy = i => i.Asc(p => p.CREATE_TIME); if (realOrders == null || !realOrders.Any()) { realOrders = new Dictionary { { "CREATE_TIME", DbOrder.DESC } }; } if (dbCount == 1 || tempStartIndex == 0) { foreach (var conn in conns) { using (var context = new EfDbContext(conn)) { var contextEntities = context.GetOrderPageEntities(exp, realOrders, selectFields?.ToArray(), tempPageSize, tempStartIndex, null, isTracking, realPaths); totalCount += contextEntities.TotalCount; if (contextEntities.Items.Any()) { var dbConn = TenantInfoMiddleware.EnDbConn(conn); contextEntities.Items.ForEach(i => i.DbConn = dbConn); entities.AddRange(contextEntities.Items); } } } //排序 if (dbCount > 1) { entities = ReOrderBy(realOrders, entities); entities = entities.Skip(tempStartIndex).Take(tempPageSize).ToList(); } } else { var perStartIndex = tempStartIndex / dbCount; Dictionary> dbEntities = new Dictionary>(); Dictionary entityCount = new Dictionary(); //第一次查询确定范围 var connIndex = 0; var type = typeof(T); var order = realOrders.FirstOrDefault(); //获取字段 var prop = type.GetProperty(order.Key); var propType = prop.PropertyType; //GetGenericTypeDefinition if (propType.FullName.Contains(typeof(Nullable).ToString())) { propType = Nullable.GetUnderlyingType(propType); } var totalEnties = new List(); foreach (var conn in conns) { using (var context = new EfDbContext(conn)) { var contextEntities = context.GetOrderPageEntities(exp, realOrders, selectFields?.ToArray(), tempPageSize, perStartIndex, null, isTracking, realPaths); totalCount += contextEntities.TotalCount; if (contextEntities.Items.Any()) { dbEntities.Add(connIndex, contextEntities.Items.ToList()); entityCount.Add(connIndex, contextEntities.Items.Count()); totalEnties.AddRange(contextEntities.Items); } else { dbEntities.Add(connIndex, new List()); entityCount.Add(connIndex, 0); } } connIndex++; } //重新排序 if (totalEnties.Count > 0) { totalEnties = ReOrderBy(realOrders, totalEnties); //最小/最大 if (exp == null) exp = t => true; var pointTime = DateTime.Now; FilterRule rule = new FilterRule(); rule.Field = order.Key; if (propType.Name == "DateTime") { rule.Value = ((DateTime)prop.GetValue(totalEnties.FirstOrDefault())).ToString("yyyy-MM-dd HH:mm:ss.ffffff"); } else { rule.Value = prop.GetValue(totalEnties.FirstOrDefault()).ToString(); } if (order.Value.ToString() == "DESC") { rule.Operate = FilterOperate.LessThanOrEqual; } else { rule.Operate = FilterOperate.GreaterThanOrEqual; } var filterExp = rule.BuildExpression(); exp = exp.And(filterExp); } //第二次查询 connIndex = 0; totalEnties.Clear(); var oldOffSet = perStartIndex * dbCount; foreach (var conn in conns) { var express = exp; using (var context = new EfDbContext(conn)) { if (dbEntities[connIndex].Count > 0) { FilterRule rule = new FilterRule(); rule.Field = order.Key; if (propType.Name == "DateTime") { rule.Value = ((DateTime)prop.GetValue(dbEntities[connIndex].LastOrDefault())).ToString("yyyy-MM-dd HH:mm:ss.ffffff"); } else { rule.Value = prop.GetValue(dbEntities[connIndex].LastOrDefault()).ToString(); } if (order.Value.ToString() == "DESC") { rule.Operate = FilterOperate.GreaterThanOrEqual; } else { rule.Operate = FilterOperate.LessThanOrEqual; } var filterExp = rule.BuildExpression(); express = express.And(filterExp); } var contextEntities = context.GetEntities(express, selectFields?.ToArray(), isTracking, realPaths); if (contextEntities.Any()) { totalEnties.AddRange(contextEntities); } var moreEntitiesCount = contextEntities.Count() - entityCount[connIndex];//多出的数据条数 oldOffSet -= moreEntitiesCount; } connIndex++; } //确定全局的OffSet后,返回数据 totalEnties = ReOrderBy(realOrders, totalEnties); entities = totalEnties.Skip((tempStartIndex - oldOffSet)).Take(tempPageSize).ToList(); } } else if (pageFilter.IsSpecifyDb) { string enConn = GetSpecifyDb(pageFilter); using (var context = new EfDbContext(enConn)) { var contextEntities = context.GetOrderPageEntities(exp, realOrders, selectFields?.ToArray(), tempPageSize, tempStartIndex, orderBy, isTracking, realPaths); totalCount = contextEntities.TotalCount; if (contextEntities.Items.Any()) entities.AddRange(contextEntities.Items); } } else { totalCount = UnitWorkOrderPaged(orderBy, isTracking, realPaths, realOrders, exp, tempPageSize, tempStartIndex, selectFields, entities); } } else { totalCount = UnitWorkOrderPaged(orderBy, isTracking, realPaths, realOrders, exp, tempPageSize, tempStartIndex, selectFields, entities); } ret.Items = entities; ret.TotalCount = totalCount; return ret; } private int UnitWorkOrderPaged(Action> orderBy, bool isTracking, string[] realPaths, Dictionary realOrders, Expression> exp, int tempPageSize, int tempStartIndex, List selectFields, List entities) where T : MesEntityBase, new() { int totalCount; var contextEntities = this.UnitOfWork.GetOrderPageEntities(exp, realOrders, selectFields?.ToArray(), tempPageSize, tempStartIndex, orderBy, isTracking, realPaths); totalCount = contextEntities.TotalCount; if (contextEntities.Items.Any()) { entities.AddRange(contextEntities.Items); } return totalCount; } private static List ReOrderBy(Dictionary realOrders, List entities) where T : MesEntityBase, new() { var queryable = entities.AsQueryable(); queryable = queryable.SetQueryableOrder(realOrders.FirstOrDefault().Key, realOrders.FirstOrDefault().Value.ToString()); var linq = new Orderable(queryable); queryable = linq.Queryable; entities = queryable.ToList(); return entities; } public PagedResultDto GetOrderPageEntities(Expression> expression, BasePageFilter pageFilter, string[] selectField, params string[] paths) where T : MesEntityBase, new() { if (pageFilter == null) pageFilter = new BasePageFilter(); pageFilter.SelectField = selectField; return this.GetOrderPageEntities(expression, pageFilter, paths); } private void NavigationDeal(string[] realPaths, IEnumerable list, string[] selecedFields, string[] dataRules, List orgRules, Guid? orgId, bool isIgnoreOrgRule, bool isIgnoreDataRule, bool isNoTranking, bool isMultipleDb, bool isSpecifyDb, string specifyDbConn) where T : MesEntityBase, new() { if (realPaths != null && realPaths.Any()) { //var tmpList = list; var hasDataList = new Hashtable(); hasDataList["."] = list; var hasDealNavPath = new List(); foreach (var path in realPaths) { var splitPaths = path.Split('.').ToArray(); var type = typeof(T); var curentPath = "."; var isICollection = false; var navTableName = ""; foreach (var spath in splitPaths) { navTableName += spath + "."; dynamic curentList = hasDataList[curentPath]; if (curentList == null) break; PropertyInfo navProp = null; PropertyInfo idProp = null; var fieldInfos = type.GetProperties(); var theType = type; EFModelForeignKey foreignKey = null; var isOneOnOne = false; foreach (var p in fieldInfos) { if (p.Name == spath) { navProp = p; type = p.PropertyType; isICollection = false; foreignKey = this.UnitOfWork.GetModelForeignKey(theType.Name, spath); if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type)) { isICollection = true; var generTypeFullName = type.GenericTypeArguments[0].FullName; type = ReflectHelper.FindTypeInCurrentDomain(generTypeFullName); idProp = type.GetProperty(foreignKey.ForeignFieldName); } else { idProp = theType.GetProperty(foreignKey.ForeignFieldName); if (idProp == null) { idProp = theType.GetProperty("ID"); isOneOnOne = true; } } break; } } if (idProp == null || navProp == null) throw new Exception($"导航属性{path}中的{spath}属性异常,请确认"); curentPath += "/" + navProp.Name; if (!hasDealNavPath.Contains(navTableName)) { //筛选字段 List typeSelectFields = new List(); foreach (var f in selecedFields) { //导航属性 if (f.StartsWith(navTableName)) { var tmpField = f.Replace(navTableName, ""); if (tmpField.IndexOf(".") < 0) typeSelectFields.Add(tmpField); else { //为了增加下级的导航属性 var nextNavIndex = tmpField.IndexOf("."); var navField = tmpField.Substring(0, nextNavIndex); if (!typeSelectFields.Contains(navField)) typeSelectFields.Add(navField); } } } BaseFilter filter = new BaseFilter(); filter.SelectField = typeSelectFields; filter.DataRule = dataRules; filter.IgnoreDataRule = isIgnoreDataRule; filter.IsNoTranking = isNoTranking; filter.OrgId = orgId; filter.IgnoreOrgRule = isIgnoreOrgRule; filter.OrgRule = orgRules; filter.IsMultipleDb = isMultipleDb; filter.IsSpecifyDb = isSpecifyDb; filter.SpecifyDbConn = specifyDbConn; List ids = new List(); if (!typeSelectFields.Contains("ID")) typeSelectFields.Add("ID"); if (isOneOnOne) typeSelectFields.Add(foreignKey.ForeignFieldName); //增加外键的查询 var methodInfo = this.GetType().GetMethod("AppendSelectedField", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static); if (methodInfo != null) { methodInfo.MakeGenericMethod(type).Invoke(this, new object[] { typeSelectFields }); } //this.GetType().GetMethod("AppendSelectedField", new Type[] { typeof(string[]) }) // .MakeGenericMethod(type).Invoke(this, new object[] { selecedFields }); //集合 //var filterGroup = new FilterGroup(); //filter.FilterGroup.Groups.Add(filterGroup); //filterGroup.IsAnd = false; List filterRules = new List(); bool searchFlag = false; if (isICollection)//对多 { if (!typeSelectFields.Contains(idProp.Name)) typeSelectFields.Add(idProp.Name); foreach (var obj in curentList) { if (obj.ID != null) { var val = Convert.ToString(obj.ID); if (!string.IsNullOrEmpty(val) && !filterRules.Any(x => x.Value.ToString() == val)) { FilterRule rule = new FilterRule(); rule.Field = idProp.Name; rule.Operate = FilterOperate.Equal; rule.Value = val; //filterGroup.Rules.Add(rule); filterRules.Add(rule); searchFlag = true; } } } } else//对1 { foreach (var obj in curentList) { var objVal = theType.GetProperty(idProp.Name).GetValue(obj); if (objVal != null) { var val = Convert.ToString(objVal); if (!string.IsNullOrEmpty(val) && !filterRules.Any(x => x.Value.ToString() == val)) { FilterRule newRule = new FilterRule(); newRule.Field = "ID"; if (isOneOnOne) { newRule.Field = foreignKey.ForeignFieldName; } newRule.Operate = FilterOperate.Equal; newRule.Value = val; //filterGroup.Rules.Add(newRule); filterRules.Add(newRule); searchFlag = true; } } } } if (!searchFlag) break; var getEntities = this.GetType().GetMethod("GetEntities", BindingFlags.Instance | BindingFlags.NonPublic); if (getEntities == null) { throw new Exception("GetEntities不存在此方法"); } List navLists = new List(); if (navProp != null && idProp != null) { //500查一次 int ruleLimit = 1000; var startRule = 0; var filterGroup = new FilterGroup(); filterGroup.IsAnd = false; foreach (var rule in filterRules) { startRule++; filterGroup.Rules.Add(rule); if (startRule >= ruleLimit) { GetRroupRules(type, filter, getEntities, navLists, filterGroup); filterGroup.Rules.Clear(); startRule = 0; } } if (filterGroup.Rules.Count > 0) GetRroupRules(type, filter, getEntities, navLists, filterGroup); hasDataList[curentPath] = navLists; foreach (var t in curentList) { //对1导航 if (!isICollection) { var objVal = t.GetType().GetProperty(idProp.Name).GetValue(t); if (objVal == null) continue; var navId = Convert.ToString(objVal); if (string.IsNullOrEmpty(navId)) continue; foreach (var s in navLists) { if (!isOneOnOne) { if (s.ID.ToString() == navId) { t.GetType().GetProperty(navProp.Name).SetValue(t, s); break; } } else { var val = s.GetType().GetProperty(foreignKey.ForeignFieldName).GetValue(s); if (val != null && val.ToString() == navId) { t.GetType().GetProperty(navProp.Name).SetValue(t, s); } } } } //对多导航 else { var id = t.ID.ToString(); var colNavList = type.GetListObject(); foreach (var s in navLists) { var objVal = s.GetType().GetProperty(idProp.Name).GetValue(s); if (objVal == null) continue; var navId = Convert.ToString(objVal); if (string.IsNullOrEmpty(navId)) continue; if (navId == id) { var methodInfos = colNavList.GetType().GetMethod("Add"); methodInfos.Invoke(colNavList, new object[] { s }); } } t.GetType().GetProperty(navProp.Name).SetValue(t, colNavList); } } } else { break; } hasDealNavPath.Add(navTableName); } } } } } private void GetRroupRules(Type type, BaseFilter filter, MethodInfo getEntities, List navLists, FilterGroup filterGroup) { filter.FilterGroup.Groups.Add(filterGroup); dynamic navGroupList = getEntities.MakeGenericMethod(type).Invoke(this, new object[] { filter }); if (navGroupList != null) { navLists.AddRange(navGroupList); } } // public async Task> GetOrderPageEntitiesSync(Expression> expression, BasePageFilter pageFilter, params string[] paths) where T : MesEntityBase, new() { return await this.GetOrderPageEntitiesSync(expression, pageFilter, 0, 0, paths); } public async Task> GetOrderPageEntitiesSync(Expression> expression, BasePageFilter pageFilter, int pageSize, int startIndex, params string[] paths) where T : MesEntityBase, new() { return await this.GetOrderPageEntitiesSync(expression, pageFilter, pageSize, startIndex, (!pageFilter?.IsNoTranking) ?? true, paths); } public async Task> GetOrderPageEntitiesSync(Expression> expression, BasePageFilter pageFilter, int pageSize, int startIndex, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { return await this.GetOrderPageEntitiesSync(expression, pageFilter, null, pageSize, startIndex, isTracking, paths); } public async Task> GetOrderPageEntitiesSync(Expression> expression, BasePageFilter pageFilter, Dictionary orders, int pageSize, int startIndex, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { return await this.GetOrderPageEntitiesSync(expression, pageFilter, orders, pageSize, startIndex, null, isTracking, paths); } public async Task> GetOrderPageEntitiesSync(Expression> expression, BasePageFilter pageFilter, Dictionary orders, int pageSize, int startIndex, Action> orderBy, bool isTracking = true, params string[] paths) where T : MesEntityBase, new() { string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, pageFilter, paths, orders, out orgExpression, out realPaths, out realOrders, false); int tempPageSize = 0; int tempStartIndex = 0; if (pageSize != 0) { tempPageSize = pageSize; tempStartIndex = startIndex; } else if (pageFilter != null) { tempStartIndex = pageFilter.Start; tempPageSize = pageFilter.Limit; } var ret = await this.UnitOfWork.GetOrderPageEntitiesSync(exp, realOrders, tempPageSize, tempStartIndex, orderBy, isTracking, realPaths); if (ret != null && ret.Items.Any()) this.FillGetEntitySysParam(ret.Items, pageFilter, paths); return ret; } public T GetEntityByRedis(string key, Guid orgid) where T : MesEntityBase, new() { var realOrgId = Api.AppContext.CurrentSession?.RootOrgId ?? orgid; Guid guidKey = Guid.Empty; if (Guid.TryParse(key, out guidKey)) { return GetEntityByRedisMethod(key, realOrgId, true).Result; } else { return GetEntityByRedisMethod(key, realOrgId, false).Result; } } public T GetEntityByRedis(Guid key, Guid orgid) where T : MesEntityBase, new() { var realOrgId = Api.AppContext.CurrentSession?.RootOrgId ?? orgid; return GetEntityByRedisMethod(key.ToString(), realOrgId, true).Result; } private async Task GetEntityByRedisMethod(string key, Guid orgid, bool isGuid) where T : MesEntityBase, new() { // CsRedisManager manager = ServiceLocator.Instance.GetService(); var type = typeof(T); //manager. var perKey = "{" + type.Name + "}"; var keys = perKey + "_" + key + "_" + orgid; T entity = null; if (CsRedisManager.KeyExists(keys) && ConfigurationManager.IsRedis) entity = await CsRedisManager.StringGetAsync(keys); else { var baseFilter = new BaseFilter(orgid); baseFilter.IsNoTranking = true; baseFilter.IgnoreDataRule = true; var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass != null) { if (redisClass.DicKeys.Any()) { var filterGroup = new FilterGroup(); filterGroup.IsAnd = false; foreach (var redisKey in redisClass.DicKeys) { if (!isGuid && redisKey.Key.EndsWith("ID")) { //不是ID类型,并且是ID字段,则不增加条件 } else { filterGroup.Rules.Add(new FilterRule(redisKey.Key, key, FilterOperate.Equal)); } } baseFilter.FilterGroup.Groups.Add(filterGroup); } else { throw new Exception("未配置rediskey"); } } else { throw new Exception("未配置成redis类型"); } entity = this.GetEntity(null, baseFilter); if (entity != null && ConfigurationManager.IsRedis) { await CsRedisManager.StringSetAsync(keys, entity); } } return entity; } public List GetEntitiesByRedis(Expression> expression, BaseFilter filter) where T : MesEntityBase, new() { filter.SelectField = new string[] { }; var realOrgId = Api.AppContext.CurrentSession?.RootOrgId ?? filter.OrgId; filter.OrgId = realOrgId; var list = GetEntitiesByRedis(filter).Result; if (expression != null) list = list.Where(expression.Compile()).ToList(); return list; } public bool IsAny(Expression> expression, BaseFilter filter) where T : MesEntityBase, new() { string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, filter, null, null, out orgExpression, out realPaths, out realOrders, false); return this.UnitOfWork.GetCount(exp) > 0; } public int GetCount(Expression> expression, BaseFilter filter) where T : MesEntityBase, new() { string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, filter, null, null, out orgExpression, out realPaths, out realOrders, false); return this.UnitOfWork.GetCount(exp); } public async Task> GetEntitiesTableByRedis(Expression> expression, BaseFilter filter, params string[] paths) where T : MesEntityBase, new() { filter.SelectField = new string[] { }; var realOrgId = Api.AppContext.CurrentSession?.RootOrgId ?? filter.GetOrgId(); if (!ConfigurationManager.IsRedis) { return this.GetOrderEntities(expression, filter, (!filter?.IsNoTranking) ?? true, paths).ToList(); } string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, filter, paths, null, out orgExpression, out realPaths, out realOrders, true); var list = await GetEntitiesByRedis(filter); if (list == null || !list.Any()) return list; if (realPaths != null && realPaths.Any()) { //var tmpList = list; var hasDataList = new Hashtable(); hasDataList["."] = list; foreach (var path in realPaths) { var splitPaths = path.Split('.').ToArray(); var type = typeof(T); var hasDealNavPath = new List(); var curentPath = "."; var isICollection = false; foreach (var spath in splitPaths) { dynamic curentList = hasDataList[curentPath]; if (curentList == null) break; if (!hasDealNavPath.Contains(spath)) { PropertyInfo navProp = null; PropertyInfo idProp = null; var fieldInfos = type.GetProperties(); var theType = type; foreach (var p in fieldInfos) { if (p.Name == spath) { navProp = p; type = p.PropertyType; isICollection = false; var foreignKey = this.UnitOfWork.GetModelForeignKey(theType.Name, spath); if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type)) { isICollection = true; var generTypeFullName = type.GenericTypeArguments[0].FullName; type = ReflectHelper.FindTypeInCurrentDomain(generTypeFullName); idProp = type.GetProperty(foreignKey.ForeignFieldName); } else { idProp = theType.GetProperty(foreignKey.ForeignFieldName); } break; } } if (navProp != null && idProp != null) { var methodInfo = (Task)this.GetType().GetMethod("GetEntitiesByRedis", new Type[] { typeof(BaseFilter) }) .MakeGenericMethod(type).Invoke(this, new object[] { filter }); //dynamic navLists = methodInfo.MakeGenericMethod(type).Invoke(this, new object[] { filter.OrgId }); await methodInfo; dynamic navLists = methodInfo.GetType().GetProperty("Result").GetValue(methodInfo); List navList = new List(); curentPath += "/" + navProp.Name; hasDataList[curentPath] = navList; foreach (var t in curentList) { //对1导航 if (!isICollection) { var navId = t.GetType().GetProperty(idProp.Name).GetValue(t).ToString(); foreach (var s in navLists) { if (s.ID.ToString() == navId) { navList.Add(s); t.GetType().GetProperty(navProp.Name).SetValue(t, s); break; } } } //对多导航 else { var id = t.ID.ToString(); var colNavList = type.GetListObject(); foreach (var s in navLists) { if (s.GetType().GetProperty(idProp.Name).GetValue(s).ToString() == id) { var methodInfos = colNavList.GetType().GetMethod("Add"); methodInfos.Invoke(colNavList, new object[] { s }); navList.Add(s); } } t.GetType().GetProperty(navProp.Name).SetValue(t, colNavList); } } } else { break; } hasDealNavPath.Add(spath); } } } } //排序和过滤 if (exp != null) { list = list.Where(exp.Compile()).ToList(); } if (!string.IsNullOrEmpty(filter.Sort)) { if (filter.Order == DbOrder.ASC) { var query = list.AsQueryable().OrderByName(filter.Sort); list = query.ToList(); } else { var query = list.AsQueryable().OrderByName(filter.Sort, true); list = query.ToList(); } } return list; } public async Task> GetEntitiesByRedis(Expression> expression, BaseFilter filter, string groupValue, params string[] paths) where T : MesEntityBase, new() { filter.SelectField = new string[] { }; var realOrgId = Api.AppContext.CurrentSession?.RootOrgId ?? filter.GetOrgId(); filter.OrgId = realOrgId; if (!ConfigurationManager.IsRedis) { var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass == null) { throw new Exception("实体未配置成redis类型"); } var groupId = redisClass.GroupName; if (!string.IsNullOrEmpty(groupValue)) { FilterRule rule = new FilterRule(); rule.Field = groupId; rule.Operate = FilterOperate.Equal; rule.Value = groupValue; filter.FilterGroup.Rules.Add(rule); } return this.GetEntities(expression, filter, false, paths).ToList(); } string[] realPaths = null; Dictionary realOrders = null; Expression> orgExpression; var exp = DoGetEntityExp(expression, filter, paths, null, out orgExpression, out realPaths, out realOrders, true); List list; if (string.IsNullOrEmpty(groupValue)) list = await GetEntitiesByRedis(filter); else list = await GetEntitiesByGroupRedis(filter, groupValue); if (list == null || !list.Any()) return list; if (realPaths != null && realPaths.Any()) { //var tmpList = list; var hasDataList = new Hashtable(); hasDataList["."] = list; foreach (var path in realPaths) { var splitPaths = path.Split('.').ToArray(); var type = typeof(T); var hasDealNavPath = new List(); var curentPath = "."; var isICollection = false; foreach (var spath in splitPaths) { dynamic curentList = hasDataList[curentPath]; if (curentList == null) break; if (!hasDealNavPath.Contains(spath)) { PropertyInfo navProp = null; PropertyInfo idProp = null; var fieldInfos = type.GetProperties(); var theType = type; foreach (var p in fieldInfos) { if (p.Name == spath) { navProp = p; type = p.PropertyType; isICollection = false; var foreignKey = this.UnitOfWork.GetModelForeignKey(theType.Name, spath); if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type)) { isICollection = true; var generTypeFullName = type.GenericTypeArguments[0].FullName; type = ReflectHelper.FindTypeInCurrentDomain(generTypeFullName); idProp = type.GetProperty(foreignKey.ForeignFieldName); } else { idProp = theType.GetProperty(foreignKey.ForeignFieldName); } break; } } if (navProp != null && idProp != null) { var methodInfo = (Task)this.GetType().GetMethod("GetEntitiesByRedis", new Type[] { typeof(BaseFilter) }) .MakeGenericMethod(type).Invoke(this, new object[] { filter }); //dynamic navLists = methodInfo.MakeGenericMethod(type).Invoke(this, new object[] { filter.OrgId }); await methodInfo; dynamic navLists = methodInfo.GetType().GetProperty("Result").GetValue(methodInfo); List navList = new List(); curentPath += "/" + navProp.Name; hasDataList[curentPath] = navList; foreach (var t in curentList) { //对1导航 if (!isICollection) { var navIdObj = t.GetType().GetProperty(idProp.Name).GetValue(t); if (navIdObj != null) { foreach (var s in navLists) { if (s.ID.ToString() == navIdObj.ToString()) { navList.Add(s); t.GetType().GetProperty(navProp.Name).SetValue(t, s); break; } } } } //对多导航 else { var id = t.ID.ToString(); var colNavList = type.GetListObject(); foreach (var s in navLists) { var idObj = s.GetType().GetProperty(idProp.Name).GetValue(s); if (idObj != null) { if (id == idObj.ToString()) { var methodInfos = colNavList.GetType().GetMethod("Add"); methodInfos.Invoke(colNavList, new object[] { s }); navList.Add(s); } } } t.GetType().GetProperty(navProp.Name).SetValue(t, colNavList); } } } else { break; } hasDealNavPath.Add(spath); } } } } //排序和过滤 if (exp != null) { var filterList = list.Where(exp.Compile()); if (filterList != null && filterList.Any()) list = filterList.ToList(); else list = new List(); } if (!string.IsNullOrEmpty(filter.Sort)) { if (filter.Order == DbOrder.ASC) { var query = list.AsQueryable().OrderByName(filter.Sort); list = query.ToList(); } else { var query = list.AsQueryable().OrderByName(filter.Sort, true); list = query.ToList(); } } return list; } public PagedResultDto GetOrderPageByRedis(Expression> expression, BasePageFilter pageFilter, params string[] paths) where T : MesEntityBase, new() { var list = GetEntitiesTableByRedis(expression, pageFilter, paths).Result; var returnDto = new PagedResultDto(); returnDto.TotalCount = list.Count(); returnDto.Items = list.Skip(pageFilter.Start).Take(pageFilter.Limit).ToList(); return returnDto; } static IEnumerable GetExtensionMethods(Assembly assembly, Type extendedType) { var query = from type in assembly.GetTypes() where !type.IsGenericType && !type.IsNested from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false) where method.GetParameters()[0].ParameterType == extendedType select method; return query; } public async Task> GetEntitiesByRedis(BaseFilter filter) where T : MesEntityBase, new() { filter.SelectField = new string[] { }; var orgid = Api.AppContext.CurrentSession?.RootOrgId ?? filter.OrgId; filter.OrgId = orgid; var tmpFilter = filter.DeepCloneObject(); if (filter != null && Api.AppContext.CurrentSession.DataRule != null && !filter.IgnoreDataRule && !filter.DataRule.Any()) { filter.DataRule = Api.AppContext.CurrentSession.DataRule; } if (!ConfigurationManager.IsRedis) { return this.GetEntities(null, tmpFilter, false).ToList(); } var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass == null) { throw new Exception("实体未配置成redis类型"); } var groupId = redisClass.GroupName; //CsRedisManager manager = ServiceLocator.Instance.GetService(); var type = typeof(T); var perKey = type.Name; var list = new List(); var isUpdateRedis = false; if (!string.IsNullOrEmpty(groupId) && groupId != "ID") { var groupkeys = "opt_grouplist_" + perKey + "_" + orgid; if (CsRedisManager.KeyExists(groupkeys)) { var keyList = await CsRedisManager.GetClient().HGetAllAsync(groupkeys); var baseFilter = new BaseFilter(orgid); baseFilter.DataRule = tmpFilter.DataRule; baseFilter.IgnoreDataRule = tmpFilter.IgnoreDataRule; foreach (var k in keyList) { //var datakeys = "sort_" + perKey + "_" + k.Value + "_" + orgid; List keyData; try { if (CsRedisManager.KeyExists(k.Value)) { keyData = await CsRedisManager.StringGetAsync>(k.Value); if (keyData != null && keyData.Any()) list.AddRange(keyData); } else { FilterRule rule = new FilterRule(); rule.Field = groupId; rule.Operate = FilterOperate.Equal; rule.Value = k.Key; baseFilter.FilterGroup.Rules.Add(rule); keyData = this.GetEntities(null, baseFilter, false).ToList(); if (keyData != null && keyData.Any()) { list.AddRange(keyData); isUpdateRedis = true; } } } catch (Exception) { if (CsRedisManager.GetClient().HExists(groupkeys, k.Key)) { await CsRedisManager.GetClient().HDelAsync(groupkeys, k.Key); } continue; } } if (isUpdateRedis) { var groupList = list.GroupByMany(groupId); foreach (var item in groupList) { if (item.Key != null) { string datakey = string.Join(',', item.Key); var keys = "sort_" + redisClass.ClassName + "_" + datakey + "_" + orgid; await CsRedisManager.StringSetAsync(keys, item.Items); //var groupkey = "opt_grouplist_" + type.Name + "_" + orgid; await CsRedisManager.GetClient().HSetAsync(groupkeys, datakey, keys); } } } } else { list = await SetRedisValue(tmpFilter, type, null); } } else { var keys = "sort_" + perKey + "_" + orgid; if (CsRedisManager.KeyExists(keys)) { list = await CsRedisManager.StringGetAsync>(keys); if (list != null) { list = list.Where(i => i != null).ToList(); } else { await CsRedisManager.KeyDeleteAsync(keys); list = await SetRedisValue(tmpFilter, type, null); } } else { list = await SetRedisValue(tmpFilter, type, null); } //var distinctList = list.Distinct().ToList(); var cList = list.Where((x, i) => list.FindIndex(z => z.ID == x.ID) == i).ToList(); if (list.Count != cList.Count) { await CsRedisManager.KeyDeleteAsync(keys); list = await SetRedisValue(tmpFilter, type, null); } } //manager. return list; } public async Task> GetEntitiesByGroupRedis(BaseFilter filter, string groupValue) where T : MesEntityBase, new() { filter.SelectField = new string[] { }; var orgid = Api.AppContext.CurrentSession?.RootOrgId ?? filter.OrgId; filter.OrgId = orgid; var tmpFilter = filter.DeepCloneObject(); var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass == null) { throw new Exception("实体未配置成redis类型"); } var groupId = redisClass.GroupName; if (!ConfigurationManager.IsRedis) { //BaseFilter filter = new BaseFilter(orgid); if (!string.IsNullOrEmpty(groupId) && groupId != "ID") { if (!string.IsNullOrEmpty(groupValue)) { FilterRule rule = new FilterRule(); rule.Field = groupId; rule.Operate = FilterOperate.Equal; rule.Value = groupValue; tmpFilter.FilterGroup.Rules.Add(rule); } } return this.GetEntities(null, tmpFilter, false).ToList(); } //CsRedisManager manager = ServiceLocator.Instance.GetService(); var type = typeof(T); var perKey = type.Name; var list = new List(); if (!string.IsNullOrEmpty(groupId) && groupId != "ID") { var groupkeys = "opt_grouplist_" + perKey + "_" + orgid; if (CsRedisManager.KeyExists(groupkeys)) { //var datakeys = "sort_" + perKey + "_" + groupValue + "_" + orgid; if (CsRedisManager.GetClient().HExists(groupkeys, groupValue)) { var data = await CsRedisManager.GetClient().HGetAsync(groupkeys, groupValue); if (!string.IsNullOrEmpty(data)) { try { List keyData = await CsRedisManager.StringGetAsync>(data); if (keyData != null && keyData.Any()) list.AddRange(keyData); else { await CsRedisManager.GetClient().DelAsync(groupkeys); list = await SetRedisValue(tmpFilter, type, groupValue); } } catch { await CsRedisManager.GetClient().DelAsync(groupkeys); list = await SetRedisValue(tmpFilter, type, groupValue); } } else { await CsRedisManager.GetClient().DelAsync(groupkeys); } } else { list = await SetRedisValue(tmpFilter, type, groupValue); } } else { list = await SetRedisValue(tmpFilter, type, groupValue); } } else { list = await SetRedisValue(tmpFilter, type, ""); } //manager. return list; } private async Task> SetRedisValue(BaseFilter filter, Type type, string groupValue) where T : MesEntityBase, new() { var tmpFilter = filter.DeepCloneObject(); var orgid = Api.AppContext.CurrentSession?.RootOrgId ?? filter.OrgId; tmpFilter.OrgId = orgid; //var filter = new BaseFilter(orgid); var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass == null) { throw new Exception("实体未配置成redis类型"); } var groupId = redisClass.GroupName; if (!ConfigurationManager.IsRedis) { if (!string.IsNullOrEmpty(groupValue)) { FilterRule rule = new FilterRule(); rule.Field = groupId; rule.Operate = FilterOperate.Equal; rule.Value = groupValue; tmpFilter.FilterGroup.Rules.Add(rule); } return this.GetEntities(null, tmpFilter, false).ToList(); } List list; var keys = "sort_" + redisClass.ClassName + "_" + orgid; if (!string.IsNullOrEmpty(groupId) && groupId != "ID") { if (!string.IsNullOrEmpty(groupValue)) { FilterRule rule = new FilterRule(); rule.Field = groupId; rule.Operate = FilterOperate.Equal; rule.Value = groupValue; tmpFilter.FilterGroup.Rules.Add(rule); } list = this.GetEntities(null, tmpFilter, false).ToList(); var groupList = list.GroupByMany(groupId); if (!string.IsNullOrEmpty(groupValue)) { if (!groupList.Any(x => Convert.ToString(x.Key) == groupValue)) { keys = "sort_" + redisClass.ClassName + "_" + groupValue + "_" + orgid; await CsRedisManager.StringSetAsync(keys, new List()); var groupkeys = "opt_grouplist_" + type.Name + "_" + orgid; await CsRedisManager.GetClient().HSetAsync(groupkeys, groupValue, keys); } } foreach (var item in groupList) { //string datakey = string.Join(',', item.Key); string datakey = item.Key == null ? "" : item.Key.ToString(); keys = "sort_" + redisClass.ClassName + "_" + datakey + "_" + orgid; await CsRedisManager.StringSetAsync(keys, item.Items); var groupkeys = "opt_grouplist_" + type.Name + "_" + orgid; await CsRedisManager.GetClient().HSetAsync(groupkeys, datakey, keys); } } else { list = this.GetEntities(null, tmpFilter, false).ToList(); await CsRedisManager.StringSetAsync(keys, list); await CsRedisManager.GetClient().HSetAsync("opt_list_" + orgid, type.Name, keys); } return list; } private void SetRedis(T entity, RedisHanddle handdle) where T : MesEntityBase, new() { if (!ConfigurationManager.IsRedis) return; try { //CsRedisManager redisHelper = ServiceLocator.Instance.GetService(); var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass != null) { var type = typeof(T); //manager. var perKey = "{" + type.Name + "}"; //1.处理 redisstring if (!redisClass.DicKeys.Any()) { redisClass.DicKeys.Add("ID", "GUID"); } var redisKeys = redisClass.DicKeys.Distinct(); foreach (var redisKey in redisKeys) { var propvalue = type.GetProperty(redisKey.Key).GetValue(entity); var filedKey = perKey + "_" + propvalue + "_" + entity.ORG_ID;//string if (handdle == RedisHanddle.Update || handdle == RedisHanddle.Add) { CsRedisManager.StringSetAsync(filedKey, entity).Wait(); } else if (handdle == RedisHanddle.Delete) { CsRedisManager.KeyDeleteAsync(filedKey).Wait(); } else { CsRedisManager.StringSetAsync(filedKey, entity).Wait(); } } //2.处理sortlist //SetRedisValue(entity.ORG_ID ?? Guid.Empty, redisHelper, type, keys).Wait(); var groupValue = redisClass.GroupName; //CsRedisManager manager = ServiceLocator.Instance.GetService(); if (!string.IsNullOrEmpty(groupValue) && groupValue != "ID") { var keys = "sort_" + redisClass.ClassName + "_" + groupValue + "_" + entity.ORG_ID; if (CsRedisManager.KeyExists(keys)) CsRedisManager.KeyDelete(keys); var groupkeys = "opt_grouplist_" + type.Name + "_" + entity.ORG_ID; if (CsRedisManager.KeyExists(groupkeys)) { CsRedisManager.KeyDelete(groupkeys); } //因为数据库可能还没提交,所以不能更新redis //SetRedisValue(entity.ORG_ID ?? Guid.Empty, redisHelper, type, //type.GetProperty(groupValue).GetValue(entity).ToString()).Wait(); } else { var keys = "sort_" + redisClass.ClassName + "_" + entity.ORG_ID; var listKeys = "opt_list_" + entity.ORG_ID; if (CsRedisManager.KeyExists(keys)) CsRedisManager.KeyDeleteAsync(keys).Wait(); if (CsRedisManager.GetClient().HExists(listKeys, perKey)) { CsRedisManager.GetClient().HDelAsync(listKeys, perKey).Wait(); } //SetRedisValue(entity.ORG_ID ?? Guid.Empty, redisHelper, type, null).Wait(); } //if (redisHelper.KeyExists(keys)) // redisHelper.KeyDeleteAsync(keys).Wait(); /* redis数据不一致的问题,一旦出现变更,则清除redis*/ /* var sortFile = redisClass.SortField; if (string.IsNullOrEmpty(sortFile)) sortFile = "ID"; double souces = 0; if (redisClass.DicKeys.Any()) { var propvalue = type.GetProperty(sortFile).GetValue(entity).ToString(); double.TryParse(propvalue, out souces); } if (handdle == RedisHanddle.Update || handdle == RedisHanddle.Add) { var lists = redisHelper.SortedSetRangeByRank(keys); var oldEntitys = lists.Where(i => i.ID == entity.ID).ToList(); if (oldEntitys.Any()) { oldEntitys = oldEntitys.OrderBy(i => i.MODIFY_TIME).ToList(); SortedSetEntry oldRd = new SortedSetEntry(); for (var o = 0; o < oldEntitys.Count; o++) { if (souces == 0) { if (o == oldEntitys.Count - 1) { var json = redisHelper.ConvertJson(oldEntitys[o]); oldRd = redisHelper.SortedSetScan(keys, json).FirstOrDefault(); if (oldRd != null) { souces = oldRd.Score; } } } redisHelper.SortedSetRemove(keys, oldEntitys[o]); } } if (souces == 0) { redisHelper.SortedSetAdd(keys, entity, lists.Count + 1); } else { redisHelper.SortedSetAdd(keys, entity, souces); } } else if (handdle == RedisHanddle.Delete) { var lists = redisHelper.SortedSetRangeByRank(keys); var oldEntity = lists.Where(i => i.ID == entity.ID).ToList(); if (oldEntity.Any()) { foreach (var en in oldEntity) { redisHelper.SortedSetRemove(keys, en); } } } else { redisHelper.SortedSetAdd(keys, entity, souces); }*/ } } catch (Exception ex) { throw ex; } } private List DynamicSelect(string[] selectField, IQueryable queryTable) { var selectSql = "New("; foreach (var s in selectField) { selectSql += s + ","; } selectSql = selectSql.Trim(','); selectSql += ")"; var result = queryTable.Select(selectSql).ToDynamicList(); return result; } private void DelRedis(IEnumerable entitys) where T : MesEntityBase, new() { if (!ConfigurationManager.IsRedis || entitys == null || !entitys.Any()) return; try { //CsRedisManager redisHelper = ServiceLocator.Instance.GetService(); var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass != null) { var type = typeof(T); //manager. var perKey = "{" + type.Name + "}"; //1.处理 redisstring if (!redisClass.DicKeys.Any()) { redisClass.DicKeys.Add("ID", "GUID"); } var redisKeys = redisClass.DicKeys.Distinct(); var selectEntiys = DynamicSelect(redisKeys.Select(i => i.Key).ToArray(), entitys.AsQueryable()); List keys = new List(); var dyType = selectEntiys.FirstOrDefault().GetType(); var orgId = entitys.FirstOrDefault().ORG_ID?.ToString(); foreach (var d in selectEntiys) { foreach (var key in redisKeys) { keys.Add(perKey + "_" + dyType.GetProperty(key.Key).GetValue(d) + "_" + orgId); } } CsRedisManager.GetClient().Del(keys.ToArray()); //2.处理sortlist //SetRedisValue(entity.ORG_ID ?? Guid.Empty, redisHelper, type, keys).Wait(); var groupValue = redisClass.GroupName; //CsRedisManager manager = ServiceLocator.Instance.GetService(); if (!string.IsNullOrEmpty(groupValue) && groupValue != "ID") { var gkeys = "sort_" + redisClass.ClassName + "_" + groupValue + "_" + orgId; if (CsRedisManager.KeyExists(gkeys)) CsRedisManager.KeyDelete(gkeys); var groupkeys = "opt_grouplist_" + type.Name + "_" + orgId; if (CsRedisManager.KeyExists(groupkeys)) { CsRedisManager.KeyDelete(groupkeys); } //因为数据库可能还没提交,所以不能更新redis //SetRedisValue(entity.ORG_ID ?? Guid.Empty, redisHelper, type, //type.GetProperty(groupValue).GetValue(entity).ToString()).Wait(); } else { var gkeys = "sort_" + redisClass.ClassName + "_" + orgId; var listKeys = "opt_list_" + orgId; if (CsRedisManager.KeyExists(gkeys)) CsRedisManager.KeyDeleteAsync(gkeys).Wait(); if (CsRedisManager.GetClient().HExists(listKeys, perKey)) { CsRedisManager.GetClient().HDelAsync(listKeys, perKey).Wait(); } } } } catch (Exception ex) { throw ex; } } private void DelRedisGroup(Guid orgId) where T : MesEntityBase, new() { if (!ConfigurationManager.IsRedis) return; try { //CsRedisManager redisHelper = ServiceLocator.Instance.GetService(); var redisClass = CsRedisHelper.GetRedisClass(); if (redisClass != null) { var type = typeof(T); //manager. var perKey = type.Name; //2.处理sortlist //SetRedisValue(entity.ORG_ID ?? Guid.Empty, redisHelper, type, keys).Wait(); var groupValue = redisClass.GroupName; //CsRedisManager manager = ServiceLocator.Instance.GetService(); if (!string.IsNullOrEmpty(groupValue) && groupValue != "ID") { var gkeys = "sort_" + redisClass.ClassName + "_" + groupValue + "_" + orgId; if (CsRedisManager.KeyExists(gkeys)) CsRedisManager.KeyDelete(gkeys); var groupkeys = "opt_grouplist_" + type.Name + "_" + orgId; if (CsRedisManager.KeyExists(groupkeys)) { CsRedisManager.KeyDelete(groupkeys); } //因为数据库可能还没提交,所以不能更新redis //SetRedisValue(entity.ORG_ID ?? Guid.Empty, redisHelper, type, //type.GetProperty(groupValue).GetValue(entity).ToString()).Wait(); } else { var gkeys = "sort_" + redisClass.ClassName + "_" + orgId; var listKeys = "opt_list_" + orgId; if (CsRedisManager.KeyExists(gkeys)) CsRedisManager.KeyDeleteAsync(gkeys).Wait(); if (CsRedisManager.GetClient().HExists(listKeys, perKey)) { CsRedisManager.GetClient().HDelAsync(listKeys, perKey).Wait(); } } } } catch (Exception ex) { throw ex; } } #region 系统参数 public void FillGetEntitySysParam(IEnumerable entities, BaseFilter filter, string[] includes) { List allIncludes = new List(); if (includes != null && includes.Any()) allIncludes.AddRange(includes); if (filter != null && filter.Include != null && filter.Include.Any()) allIncludes.AddRange(filter.Include); if (entities == null || !entities.Any() || allIncludes == null || !allIncludes.Any()) return; var first = entities.FirstOrDefault(); if (!(first is MesEntityBase)) return; List mesEntityBases = new List(); entities.ForEach(t => { mesEntityBases.Add(t as MesEntityBase); }); List ids = new List(); DoForEachEntitiesOnIncludes(mesEntityBases, null, string.Empty, allIncludes, (idPropertyInfo, obj) => { if (obj != null) { var idObj = idPropertyInfo.GetValue(obj); if (idObj != null) ids.Add(new Guid(idObj.ToString())); } }); if (!ids.Any()) return; var sysParams = this.UnitOfWork.GetEntities(t => ids.Contains(t.ENTITY_ID ?? Guid.Empty), null, false).ToList(); if (sysParams != null && sysParams.Any()) { DoForEachEntitiesOnIncludes(mesEntityBases, null, string.Empty, allIncludes, (idPropertyInfo, obj) => { if (obj != null) { var idObj = idPropertyInfo.GetValue(obj); if (idObj != null) { var id = new Guid(idObj.ToString()); var tempSysParams = sysParams.Where(t => t.ENTITY_ID == id).ToList(); if (tempSysParams != null && tempSysParams.Any()) { var navSysParamProperty = obj.GetType().GetProperty("Nav_SysParams"); if (navSysParamProperty != null) navSysParamProperty.SetValue(obj, tempSysParams); } } } }); } } private List GetSysParams(IEnumerable entities, bool isDelete = false) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return null; var first = entities.FirstOrDefault(); if (!(first is MesEntityBase)) return null; if (isDelete) { var ids = entities.Select(t => new Guid(t.ID.ToString())).ToList(); var dbParams = this.UnitOfWork.GetEntities(t => ids.Contains(t.ENTITY_ID ?? Guid.Empty), null, false).ToList(); if (dbParams.Any()) return dbParams; } List pfParams = new List(); foreach (var item in entities) { if (item.Nav_SysParams != null && item.Nav_SysParams.Any()) { pfParams.AddRange(item.Nav_SysParams); item.Nav_SysParams.ForEach(t => t.VIR_IS_DELETED = item.IS_DELETED); item.Nav_SysParams = null; } } return pfParams; } private string GetRealInclude(string p) { if (!string.IsNullOrEmpty(p)) p = p.Trim(); if (string.IsNullOrEmpty(p)) return p; int index = p.IndexOf("Nav_SysParams", StringComparison.OrdinalIgnoreCase); if (index > -1) { if (index > 0) return p.Substring(0, index - 1); else return string.Empty; } return p; } /// /// 构造关联的表 /// /// /// /// private string[] GetIncludes(BaseFilter baseFilter, params string[] paths) { Dictionary dic = new Dictionary(); if (paths != null) { foreach (string path in paths) { var temp = GetRealInclude(path); if (!string.IsNullOrEmpty(temp) && !dic.ContainsKey(temp)) dic[temp] = 0; } } if (baseFilter != null && baseFilter.Include != null) { foreach (var path in baseFilter.Include) { var temp = GetRealInclude(path); if (!string.IsNullOrEmpty(temp) && !dic.ContainsKey(temp)) dic[temp] = 0; } foreach (var path in baseFilter.SelectField.Where(i => i.IndexOf(".") > 0)) { var index = path.LastIndexOf("."); var temp = GetRealInclude(path.Substring(0, index)); if (!string.IsNullOrEmpty(temp) && !dic.ContainsKey(temp)) dic[temp] = 0; } } if (dic.Any()) return dic.Keys.ToArray(); return null; } /// /// 构造查询条件 /// /// /// /// /// /// /// /// /// private Expression> DoGetEntityExp (Expression> expression, BaseFilter parmFilter, string[] paths, IDictionary orders, out Expression> orgExpression, out string[] realPaths, out Dictionary realOrders, bool appendDataNav) where T : MesEntityBase, new() { orgExpression = t => true; BaseFilter filter = parmFilter; if (expression == null) expression = t => !t.IS_DELETED; else expression = expression.And(t => !t.IS_DELETED); var dataNavField = ""; if (filter != null) { //OrgId的过滤条件 var orgIdExpression = this.GetPermissionExpression(filter, out orgExpression); if (orgIdExpression != null) { expression = expression.And(orgIdExpression); } //原filter过滤条件 expression = expression.And(filter.BuildExpression(this.UnitOfWork)); //数据权限处理 var type = typeof(T); var dataFieldAttr = type.GetAttribute(); if (dataFieldAttr != null && !parmFilter.IgnoreDataRule) { Guid? nullGuid = null; var dataFieldfilter = new BaseFilter(); FilterGroup group = new FilterGroup(); group.IsAnd = false; dataFieldfilter.FilterGroup.Groups.Add(group); var splitAttrs = dataFieldAttr.FileName.Split(new char[] { '.' }); var tmpType = type; var tmpFiled = ""; if (appendDataNav) { var dataNavFieldIndex = dataFieldAttr.FileName.LastIndexOf('.'); if (dataNavFieldIndex > 0) { dataNavField = dataFieldAttr.FileName.Substring(0, dataNavFieldIndex); } } foreach (var a in splitAttrs) { var property = tmpType.GetProperty(a); var propertyClass = property.PropertyType; if (property.Name.StartsWith("Nav_")) { var keys = this.UnitOfWork.GetModelForeignKey(tmpType.Name); var key = keys.FirstOrDefault(x => x.ForeignNavName == property.Name); if (key != null) { var keyProp = tmpType.GetProperty(key.ForeignFieldName); if (keyProp != null && keyProp.PropertyType.IsNullableType()) { var emptyRule = new FilterRule(); emptyRule.Field = tmpFiled + keyProp.Name; emptyRule.Operate = FilterOperate.Equal; emptyRule.Value = nullGuid; group.Rules.Add(emptyRule); } } } else { if (property.PropertyType.IsNullableType()) { var emptyRule = new FilterRule(); emptyRule.Field = tmpFiled + property.Name; emptyRule.Operate = FilterOperate.Equal; emptyRule.Value = nullGuid; group.Rules.Add(emptyRule); } } tmpFiled += property.Name + "."; tmpType = propertyClass; } //数据权限的过滤条件 if (filter.DataRule.Any()) { foreach (var data in filter.DataRule) { var rule = new FilterRule(); rule.Field = dataFieldAttr.FileName; rule.Operate = FilterOperate.Equal; rule.Value = data; group.Rules.Add(rule); } expression = expression.And(dataFieldfilter.BuildExpression(this.UnitOfWork)); } else { expression = expression.And(t => false); } } } else { if (APT.Infrastructure.Api.AppContext.CurrentSession.RootOrgId != null) { //expression = expression.And(t => t.ORG_ID == APT.Infrastructure.Api.AppContext.CurrentSession.RootOrgId); //orgExpression = orgExpression.And(t => t.ORG_ID == APT.Infrastructure.Api.AppContext.CurrentSession.RootOrgId); } else { } } realPaths = this.GetIncludes(filter, paths); if (!string.IsNullOrEmpty(dataNavField)) { if (realPaths == null) realPaths = new string[] { dataNavField }; else realPaths = realPaths.Append(dataNavField).ToArray(); } realOrders = new Dictionary(); if (filter != null) { if (!string.IsNullOrEmpty(filter.Sort)) realOrders[filter.Sort] = filter.Order; if (filter.Orders != null && filter.Orders.Any()) foreach (var item in filter.Orders) realOrders[item.Field] = item.Order; } if (orders != null && orders.Any()) { foreach (var item in orders) { DbOrder dbOrder = DbOrder.ASC; if (item.Value == "DESC") dbOrder = DbOrder.DESC; realOrders[item.Key] = dbOrder; } } return expression; } private Expression> GetPermissionExpression(BaseFilter filter, out Expression> orgExpression) where T : MesEntityBase, new() { orgExpression = t => true; Expression> expression = t => true; if (filter.IgnoreOrgRule) { return null; if (filter.OrgId == null) return null; expression = t => t.ORG_ID == filter.OrgId; orgExpression = orgExpression.And(t => t.ORG_ID == filter.OrgId); } else { var currtOrgId = filter?.OrgId; Expression> orgPress = t => false; if (filter != null && filter.OrgRule.Any()) { foreach (var s in filter.OrgRule) { orgPress = orgPress.Or(t => t.ORG_ID == s); } } if (currtOrgId != null) orgPress = orgPress.Or(t => t.ORG_ID == currtOrgId); expression = expression.And(orgPress); orgExpression = orgExpression.And(orgPress); } return expression; #region 原组织权限模式 /* if (filter.OrgType == FilterOrgTypeEnum.默认) { var sysPermission = APT.Infrastructure.Api.AppContext.SysPermission; List parentOrgIds = new List(); List childrenOrgIds = new List(); OrgCache orgCache = null; UserOrgCache userOrgCache = null; if (sysPermission != null) { if (sysPermission.OrgCaches != null) { if (sysPermission.OrgCaches.TryGetValue(filter.OrgId.Value, out orgCache)) { if (orgCache.AllChildrenIds != null && orgCache.AllChildrenIds.Any()) childrenOrgIds.AddRange(orgCache.AllChildrenIds); if (orgCache.AllParentIds != null && orgCache.AllParentIds.Any()) parentOrgIds.AddRange(orgCache.AllParentIds); } } if (sysPermission.UserOrgCaches != null && APT.Infrastructure.Api.AppContext.CurrentSession != null && APT.Infrastructure.Api.AppContext.CurrentSession.UserID != null) { if (sysPermission.UserOrgCaches.TryGetValue(APT.Infrastructure.Api.AppContext.CurrentSession.UserID.Value, out userOrgCache)) { if (userOrgCache.Orgs != null && userOrgCache.Orgs.Any()) { foreach (var org in userOrgCache.Orgs) { if (sysPermission.OrgCaches.TryGetValue(org, out orgCache)) { if (orgCache.AllChildrenIds != null && orgCache.AllChildrenIds.Any()) { var remains = orgCache.AllChildrenIds.Where(t => !childrenOrgIds.Contains(t)).ToList(); if (remains != null && remains.Any()) childrenOrgIds.AddRange(remains); } if (orgCache.AllParentIds != null && orgCache.AllParentIds.Any()) { var remains = orgCache.AllParentIds.Where(t => !parentOrgIds.Contains(t)).ToList(); if (remains != null && remains.Any()) parentOrgIds.AddRange(remains); } } } } } } } expression = t => ((t.ENTITY_ORG_TPYE == 0 || t.ENTITY_ORG_TPYE == 1) && (t.ORG_ID == filter.OrgId || childrenOrgIds.Contains(t.ORG_ID ?? Guid.Empty))) || (t.ENTITY_ORG_TPYE == 1 && (parentOrgIds.Contains(t.ORG_ID ?? Guid.Empty))) || (t.ENTITY_ORG_TPYE == 2) || (t.ENTITY_ORG_TPYE == 3 && t.ORG_ID == filter.OrgId); } else if (filter.OrgType == FilterOrgTypeEnum.仅本组织) { expression = t => t.ORG_ID == filter.OrgId; } if (expression != null) { var sysPermission = APT.Infrastructure.Api.AppContext.SysPermission; if (!string.IsNullOrEmpty(filter.AuthOrgCodes) && sysPermission != null) { var authOrgIds = new List(); var c = filter.AuthOrgCodes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var i in c) { Guid orgId; if (sysPermission.OrgCodeCaches.TryGetValue(i, out orgId)) authOrgIds.Add(orgId); } if (authOrgIds.Any()) expression = expression.Or(t => authOrgIds.Contains(t.ORG_ID ?? Guid.Empty)); } } return expression; */ #endregion } /// /// 检查唯一性 /// /// private void CheckUnique(IEnumerable entities, IEnumerable deleteEntities) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; List delIds = new List(); if (deleteEntities != null && deleteEntities.Any()) delIds = deleteEntities.Select(i => i.ID).ToList(); Type type = typeof(T); foreach (PropertyInfo item in type.GetProperties()) { CUniqueAttribute cUniqueAttr = null; object[] attrs = item.GetCustomAttributes(typeof(CUniqueAttribute), true); if (attrs.Length == 1) cUniqueAttr = (CUniqueAttribute)attrs[0]; if (cUniqueAttr == null) continue; var groupByOrgIds = entities.GroupBy(t => t.ORG_ID).ToList(); foreach (var oId in groupByOrgIds) { BaseFilter filter = new BaseFilter(); FilterGroup filterGroup = new FilterGroup(false); Guid? orgId = oId.Key; var temps = oId.ToList();// entities.Where(t => t.ORG_ID == oId).ToList(); bool checkSelf = temps.Count() == 1 ? false : true; int count = 0; foreach (var entity in temps) { PropertyInfo propertyInfo = type.GetProperty("ID"); if (propertyInfo == null) continue; object id = propertyInfo.GetValue(entity, null); if (id == null) continue; if (orgId == null) { propertyInfo = type.GetProperty("ORG_ID"); //获取指定名称的属性 if (propertyInfo == null) continue; object tmpOrgId = propertyInfo.GetValue(entity, null); //获取属性值 if (tmpOrgId != null) orgId = (Guid)tmpOrgId; } FilterGroup tmp = new FilterGroup(); object obj = item.GetValue(entity, null); if ((obj == null || string.IsNullOrEmpty(obj.ToString())) && !cUniqueAttr.IsCheckEmpty) continue; tmp.Rules.Add(new FilterRule("ID", id, FilterOperate.NotEqual)); tmp.Rules.Add(new FilterRule(item.Name, obj, FilterOperate.Equal)); filterGroup.Groups.Add(tmp); count++; if (count >= 100) { filter.FilterGroup.Groups.Add(filterGroup); DoCheckUnique(item, cUniqueAttr, filter, checkSelf, orgId, temps, entities, delIds); filter = new BaseFilter(); filterGroup = new FilterGroup(false); count = 0; } } if (filterGroup.Groups.Any()) { filter.FilterGroup.Groups.Add(filterGroup); DoCheckUnique(item, cUniqueAttr, filter, checkSelf, orgId, temps, entities, delIds); } } } } private void DoCheckUnique(PropertyInfo item, CUniqueAttribute cUniqueAttr, BaseFilter filter, bool checkSelf, Guid? orgId, IEnumerable temps, IEnumerable entities, List delIds) where T : MesEntityBase, new() { //Expression> express = null; //if (cUniqueAttr.IsCheckOrg) // express = t => t.ORG_ID == orgId; //else // express = t => true; //if (delIds.Any()) // express = t => !delIds.Contains(t.ID); //express = express.And(filter.BuildExpression(this.UnitOfWork)); //T dbEntity = null; //var hasExistRecord = false; //if (checkSelf) //{ // if (cUniqueAttr.IsCheckOrg) // hasExistRecord = temps.Where(express.Compile()).Any(); // else // hasExistRecord = entities.Where(express.Compile()).Any(); //} ////if (!hasExistRecord) ////{ //dbEntity = this.UnitOfWork.GetEntity(express, null, false); //hasExistRecord = dbEntity != null; ////} //if (hasExistRecord) //{ // if (cUniqueAttr.IsCheckOrg) // { // var dbId = dbEntity.ID; // var entity = temps.FirstOrDefault(i => i.ID == dbId); // if (entity != null) // return; // } // else // { // var dbId = dbEntity.ID; // var entity = entities.FirstOrDefault(i => i.ID == dbId); // if (entity != null) // return; // } // string displayName = string.Empty; // if (cUniqueAttr != null && !string.IsNullOrEmpty(cUniqueAttr.DisplayName)) // displayName = cUniqueAttr.DisplayName; // if (string.IsNullOrEmpty(displayName)) // { // object[] tmps = item.GetCustomAttributes(typeof(DescriptionAttribute), true); // if (tmps.Length >= 1) // { // var descAttr = (DescriptionAttribute)tmps[0]; // displayName = "字段【" + descAttr.Description + "】"; // } // } // throw new Exception(displayName + "已存在其他记录,请确认"); //} } //private void DoSetIsLeafByUpdate(IEnumerable entities, List addParentIds, List deleteParentIds, List deleteIds) // where T : MesEntityBase, new() //{ // if (entities != null) // { // var def = entities.FirstOrDefault(); // if (def != null && def is MesTreeEntityBase) // { // var ids = entities.Select(t => t.ID).ToList(); // List dbUpdateEntities = this.UnitOfWork.GetEntities(t => ids.Contains(t.ID), null, false).ToList(); // foreach (var entity in entities) // { // var dbEntity = dbUpdateEntities.FirstOrDefault(t => t.ID.ToString() == entity.ID.ToString()); // if (dbEntity != null) // { // var entityTree = entity as MesTreeEntityBase; // var dbEntityTree = dbEntity as MesTreeEntityBase; // if (entityTree.PARENT_ID != dbEntityTree.PARENT_ID) // { // if (entityTree.PARENT_ID != null) // addParentIds.Add(entityTree.PARENT_ID.Value); // if (dbEntityTree.PARENT_ID != null) // { // deleteParentIds.Add(dbEntityTree.PARENT_ID.Value); // deleteIds.Add(dbEntity.ID); // } // } // } // else // { // var entityTree = entity as MesTreeEntityBase; // if (entityTree.PARENT_ID != null) // addParentIds.Add(entityTree.PARENT_ID.Value); // } // } // } // } //} //private void DoSetIsLeaf(IEnumerable entities, List deleteIds, bool isAdd) //{ // if (entities != null) // { // var def = entities.FirstOrDefault(); // if (def != null && def is MesTreeEntityBase) // { // List parentIds = new List(); // foreach (var item in entities) // { // var treeEntity = item as MesTreeEntityBase; // if (treeEntity.PARENT_ID != null) // { // parentIds.Add(treeEntity.PARENT_ID.Value); // } // } // MethodInfo methodInfo = this.GetType().GetMethod("SetParentIsLeaf", // BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static); // methodInfo.MakeGenericMethod(new Type[] { def.GetType() }). // Invoke(this, new object[] { parentIds, deleteIds, isAdd }); // } // } //} private void SaveSysParams(List pfParams) { if (pfParams == null || !pfParams.Any()) return; var ids = pfParams.Select(t => t.ID).ToList(); var dbParams = this.UnitOfWork.GetEntities(t => ids.Contains(t.ID), null, false).ToList(); List updateParams = new List(); List deleteParams = new List(); List addParams = new List(); foreach (var item in pfParams) { var dbP = dbParams.FirstOrDefault(t => t.ID == item.ID); if (dbP != null) { if (item.VIR_IS_DELETED) { //var entry1 = this._pfParamDataSet.GetContext().Entry(dbP); // entry1.State = EntityState.Deleted; deleteParams.Add(dbP); continue; } dbP.ENTITY_ID = item.ENTITY_ID; dbP.CODE = item.CODE; dbP.VALUE = item.VALUE; //var entry = this._pfParamDataSet.GetContext().Entry(dbP); //entry.State = EntityState.Modified; updateParams.Add(dbP); } else { if (item.VIR_IS_DELETED) continue; //var entry = this._pfParamDataSet.GetContext().Entry(item); //entry.State = EntityState.Added; addParams.Add(item); } } if (addParams.Any()) this.UnitOfWork.AddEntities(addParams); if (updateParams.Any()) this.UnitOfWork.UpdateEntities(updateParams); if (deleteParams.Any()) this.UnitOfWork.DeleteEntities(deleteParams); } //public void SetParentIsLeaf(List parentIds, List deleteIds, bool isAdd) where T : MesTreeEntityBase, new() //{ // if (parentIds != null && parentIds.Any()) // { // if (isAdd) // { // var parentEntities = this.UnitOfWork.GetEntities(t => parentIds.Contains(t.ID), null, true).ToList(); // parentEntities.ForEach(item => // { // item.IS_LEAF = false; // }); // foreach (var item in parentEntities) // { // this.SetRedis(item, RedisHanddle.Update); // } // this.UnitOfWork.UpdateEntities(parentEntities); // } // else // { // var parentEntities = this.UnitOfWork.GetEntities(t => parentIds.Contains(t.ID), null, true).ToList(); // var childEntities = this.UnitOfWork.GetEntities(t => t.PARENT_ID != null && parentIds.Contains(t.PARENT_ID ?? Guid.Empty), null, true).ToList(); // List updateEntities = new List(); // parentEntities.ForEach(item => // { // var theChilds = childEntities.Where(i => i.PARENT_ID == item.ID).ToList(); // var theChildIds = theChilds.Select(i => i.ID).ToList(); // theChildIds.RemoveAll(i => deleteIds.Contains(i)); // if (!theChildIds.Any() && !item.IS_LEAF) // { // item.IS_LEAF = true; // updateEntities.Add(item); // } // }); // if (updateEntities.Count > 0) // { // foreach (var item in updateEntities) // { // this.SetRedis(item, RedisHanddle.Update); // } // this.UnitOfWork.UpdateEntities(updateEntities); // } // } // } //} /// /// /// /// /// 0-新增 1-更新 2-删除 private void UpdateSerialUsedStatus(IEnumerable entities, int updateType, List updateSerialInfos) where T : MesEntityBase, new() { return; if (entities == null || !entities.Any()) return; Type type = typeof(T); bool checkSelf = entities.Count() == 1 ? false : true; // List updateSerialInfos = new List(); List dbEntities = null; if (updateType == 1) { var ids = entities.Select(t => t.ID).ToList(); dbEntities = this.UnitOfWork.GetEntities(t => ids.Contains(t.ID), null, false).ToList(); } foreach (PropertyInfo item in type.GetProperties()) { CodeRuleAttribute cUniqueAttr = null; object[] attrs = item.GetCustomAttributes(typeof(CodeRuleAttribute), true); if (attrs.Length == 1) cUniqueAttr = (CodeRuleAttribute)attrs[0]; if (cUniqueAttr == null) continue; string displayName = string.Empty; object[] tmps = item.GetCustomAttributes(typeof(CUniqueAttribute), true); if (tmps != null && tmps.Any()) { var descAttr = (CUniqueAttribute)tmps[0]; displayName = "字段【" + descAttr.DisplayName + "】"; } if (string.IsNullOrWhiteSpace(displayName)) { tmps = item.GetCustomAttributes(typeof(DescriptionAttribute), true); if (tmps != null && tmps.Any()) { var descAttr = (DescriptionAttribute)tmps[0]; displayName = "字段【" + descAttr.Description + "】"; } } foreach (var entity in entities) { object obj = item.GetValue(entity, null); if (updateType == 0 || updateType == 2) { if (obj == null) continue; var code = obj.ToString(); if (string.IsNullOrEmpty(code)) continue; this.UpdateSerialUsedStatusSql(updateSerialInfos, cUniqueAttr, displayName, code, updateType == 0); } else { var dbEntity = dbEntities == null ? null : dbEntities.FirstOrDefault(t => t.ID.ToString() == entity.ID.ToString()); if (dbEntity != null) { object dbObj = item.GetValue(dbEntity, null); string code = obj == null ? string.Empty : obj.ToString(); string dbCode = dbObj == null ? string.Empty : dbObj.ToString(); if (string.Compare(code, dbCode, true) != 0) { if (string.IsNullOrEmpty(dbCode)) this.UpdateSerialUsedStatusSql(updateSerialInfos, cUniqueAttr, displayName, dbCode, false); if (string.IsNullOrEmpty(code)) this.UpdateSerialUsedStatusSql(updateSerialInfos, cUniqueAttr, displayName, code, true); } } } } } } private void ExcuteUpdateSerialInfos(List updateSerialInfos) { if (updateSerialInfos != null && updateSerialInfos.Any()) { List types = updateSerialInfos.SelectMany(t => t.CodeTypes).Distinct().ToList(); List serials = updateSerialInfos.Select(t => t.Serial).Distinct().ToList(); var dbSerials = this.UnitOfWork.GetEntities(t => types.Contains(t.CODE_TYPE) && serials.Contains(t.SERIAL), null, false).ToList(); List updateCodeRuleSerials = new List(); var nowTime = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); foreach (var item in updateSerialInfos) { var ss = dbSerials.Where(t => item.CodeTypes.Contains(t.CODE_TYPE) && t.SERIAL == item.Serial).ToList(); if (ss != null && ss.Any()) { ss.ForEach(t => { if (t.STATUS == 2 && item.IsUsed && item.IsCheckState) throw new Exception((string.IsNullOrEmpty(item.DisplayCodeName) ? "编号" : item.DisplayCodeName) + t.SERIAL + "已被其他用户使用,请稍后重试"); t.STATUS = item.IsUsed ? 2 : 0; t.USE_TIME = item.IsUsed ? item.Time : null; t.ROW_VERSION++; t.MODIFY_TIME = nowTime; }); updateCodeRuleSerials.AddRange(ss); } } if (updateCodeRuleSerials.Any()) this.UnitOfWork.UpdateEntities(updateCodeRuleSerials); } } private void UpdateSerialUsedStatusSql(List updateSerialInfos, CodeRuleAttribute codeRuleAttr, string displayName, string code, bool isUsed) { if (codeRuleAttr != null && codeRuleAttr.CodeRuleTypes != null && codeRuleAttr.CodeRuleTypes.Any()) { UpdateCodeSerialInfo info = new UpdateCodeSerialInfo(); info.Serial = code; info.CodeTypes.AddRange(codeRuleAttr.CodeRuleTypes); info.IsUsed = isUsed; info.Time = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); ; info.DisplayCodeName = displayName; info.IsCheckState = codeRuleAttr.IsCheckState; updateSerialInfos.Add(info); } } void CheckRowVersion(IEnumerable entities) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; bool isRowVersion = false; foreach (var item in entities) { isRowVersion = item is IRowVersion; break; } if (!isRowVersion) return; var ids = entities.Select(t => t.ID).ToList(); var dbEntities = this.UnitOfWork.GetEntities(t => ids.Contains(t.ID), null, false).ToList(); foreach (var entity in entities) { var dbEntity = dbEntities.Where(t => t.ID.ToString() == entity.ID.ToString()).FirstOrDefault(); if (dbEntity != null) { IRowVersion rowVersion = entity as IRowVersion; IRowVersion dbRowVersion = dbEntity as IRowVersion; if (rowVersion.ROW_VERSION != dbRowVersion.ROW_VERSION) throw new RowVersionException("当前数据已发生修改,请先执行查询操作"); rowVersion.ROW_VERSION += 1; } } } void CheckRowVersion(IEnumerable entities, EfDbContext contex) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; bool isRowVersion = false; foreach (var item in entities) { isRowVersion = item is IRowVersion; break; } if (!isRowVersion) return; var ids = entities.Select(t => t.ID).ToList(); var dbEntities = contex.GetEntities(t => ids.Contains(t.ID), null, false).ToList(); foreach (var entity in entities) { var dbEntity = dbEntities.Where(t => t.ID.ToString() == entity.ID.ToString()).FirstOrDefault(); if (dbEntity != null) { IRowVersion rowVersion = entity as IRowVersion; IRowVersion dbRowVersion = dbEntity as IRowVersion; if (rowVersion.ROW_VERSION != dbRowVersion.ROW_VERSION) throw new RowVersionException("当前数据已发生修改,请先执行查询操作"); rowVersion.ROW_VERSION += 1; } } } private void DoGetSysParamByEntity(MesEntityBase entityBase, MesEntityBase parentEntityBase, string parentInclude, List includes, Action action) { string path = parentInclude; if (!string.IsNullOrEmpty(path)) path += "."; path += "Nav_SysParams"; bool isInclude = includes.Contains(path); var type = entityBase.GetType(); if (isInclude) { action(type.GetProperty("ID"), entityBase); } foreach (var propertyInfo in type.GetProperties()) { var propertyType = propertyInfo.PropertyType; if (propertyType.IsGenericType) { var types = propertyType.GetGenericArguments(); Type realType = null; if (types != null && types.Any()) realType = types[0]; if (realType.IsClass) { var baseType = realType.BaseType; if (baseType == typeof(MesEntityBase) || baseType == typeof(MesTreeEntityBase)) { object obj = propertyInfo.GetValue(entityBase, null); if (obj != null && obj is System.Collections.IList) { List testBases = new List(); System.Collections.IList enumerator = obj as System.Collections.IList; for (int i = 0; i < enumerator.Count; i++) { var ix = enumerator[i]; testBases.Add(ix as MesEntityBase); } if (testBases.Any()) DoForEachEntitiesOnIncludes(testBases, entityBase, string.IsNullOrEmpty(parentInclude) ? propertyInfo.Name : (parentInclude + "." + propertyInfo.Name), includes, action); } } } } else if (propertyType.IsClass) { var baseType = propertyType.BaseType; if (baseType == typeof(MesEntityBase) || baseType == typeof(MesTreeEntityBase)) { var obj = propertyInfo.GetValue(entityBase, null); if (obj != null) { var temp = obj as MesEntityBase; if (parentEntityBase == null || parentEntityBase.ID != temp.ID) DoGetSysParamByEntity(temp, entityBase, string.IsNullOrEmpty(parentInclude) ? propertyInfo.Name : (parentInclude + "." + propertyInfo.Name), includes, action); } } } } } private void DoForEachEntitiesOnIncludes(IEnumerable entities, MesEntityBase parentEntityBase, string parentInclude, List includes, Action action) { if (entities == null || !entities.Any() || includes == null || !includes.Any() || !includes.Any(t => t.IndexOf("Nav_SysParams", StringComparison.OrdinalIgnoreCase) > -1)) return; foreach (var item in entities) DoGetSysParamByEntity(item, parentEntityBase, parentInclude, includes, action); } /// /// 设置首字母缩写字段 /// /// /// private void FillAcronymFieldData(IEnumerable entities, params string[] updateField) where T : MesEntityBase, new() { if (entities == null || !entities.Any()) return; Type type = typeof(T); foreach (var p in type.GetProperties()) { AcronymFieldAttribute acronymAttr = null; object[] attrs = p.GetCustomAttributes(typeof(AcronymFieldAttribute), true); if (attrs.Length == 1) acronymAttr = (AcronymFieldAttribute)attrs[0]; if (acronymAttr == null || string.IsNullOrEmpty(acronymAttr.AcronymFieldName)) continue; var acronymP = type.GetProperty(acronymAttr.AcronymFieldName); if (acronymP == null) continue; updateField.Append(p.Name); foreach (var entity in entities) { try { string aValue = null; var o = p.GetValue(entity, null); if (o != null) { var allSpell = AcronymHelper.ConvertToAllSpell(o.ToString()); var first = AcronymHelper.ConvertToFirstSpell(o.ToString()); aValue = first + ";" + allSpell; } acronymP.SetValue(entity, aValue); } catch { } } } } /// /// 获取所有的数据库连接 /// /// private List GetAllDbConns() { List dbs = new List(); List conns = new List(); //取redis var tenantConnKey = ConfigurationManager.AppSettings["TenantConnKey"] + "_All_" + ConfigurationManager.AppSettings["Env"]; if (CsRedisManager.KeyExists(tenantConnKey)) { conns = CsRedisManager.StringGet>(tenantConnKey); } //查询 else { var url = APT.Infrastructure.Api.ConfigurationManager.AppSettings["AllConnApiUrl"]; if (!string.IsNullOrEmpty(url)) { url += $"?deskey={DesKey}"; conns = WebUtils.Get>(url, ""); } } if (conns != null && conns.Any()) { foreach (var conn in conns) { dbs.Add(EncryptHelper.AesDecrypt(conn, DesKey)); } } return dbs; } } #endregion }