using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Storage; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using SqlSugar; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; using LM.Core.DbContext; using LM.Core.DBManager; using LM.Core.DbSqlSugar; using LM.Core.Enums; using LM.Core.Extensions; using LM.Core.Utilities; using LM.Entity; using LM.Entity.SystemModels; namespace LM.Core.BaseProvider { public abstract class RepositoryBase where TEntity : BaseEntity, new() { public RepositoryBase(VOLContext dbContext) { this.DefaultDbContext = dbContext; } private VOLContext DefaultDbContext { get; set; } public VOLContext VOLContext { get { return DefaultDbContext; } } public virtual ISqlSugarClient DbContext { get { return DefaultDbContext.SqlSugarClient; } } public virtual ISqlSugarClient SqlSugarClient { get { return DefaultDbContext.SqlSugarClient; } } private ISugarQueryable DBSet { get { return VOLContext.Set(); } } /// /// 执行事务 /// /// 如果返回false则回滚事务(可自行定义规则) /// public virtual WebResponseContent DbContextBeginTransaction(Func action) { WebResponseContent webResponse = new WebResponseContent(); try { DbContext.Ado.BeginTran(); webResponse = action(); if (webResponse.Status) { DbContext.Ado.CommitTran(); } else { DbContext.Ado.RollbackTran(); } return webResponse; } catch (Exception ex) { DbContext.Ado.RollbackTran(); return new WebResponseContent().Error(ex.Message + ex.InnerException + ex.StackTrace); } } public virtual bool Exists(Expression> predicate, bool filterDeleted = true) where TExists : class { return VOLContext.Set(filterDeleted).Any(predicate); } public virtual Task ExistsAsync(Expression> predicate, bool filterDeleted = true) where TExists : class { return VOLContext.Set(filterDeleted).AnyAsync(predicate); } public virtual bool Exists(Expression> predicate, bool filterDeleted = true) { return VOLContext.Set(filterDeleted).Any(predicate); } public virtual Task ExistsAsync(Expression> predicate, bool filterDeleted = true) { return VOLContext.Set(filterDeleted).AnyAsync(predicate); } public virtual ISugarQueryable WhereIF(bool checkCondition, Expression> predicate) { if (checkCondition) { return VOLContext.Set().Where(predicate); } return VOLContext.Set(); } public virtual ISugarQueryable WhereIF(bool checkCondition, Expression> predicate) where T : class { if (checkCondition) { return VOLContext.Set().Where(predicate); } return VOLContext.Set(); } public virtual List Find(Expression> predicate, bool filterDeleted = true) where TFind : class { return VOLContext.Set(filterDeleted).Where(predicate).ToList(); } public virtual Task FindAsyncFirst(Expression> predicate, bool filterDeleted = true) where TFind : class { return FindAsISugarQueryable(predicate, filterDeleted).FirstOrDefaultAsync(); } public virtual Task FindAsyncFirst(Expression> predicate, bool filterDeleted = true) { return FindAsISugarQueryable(predicate, filterDeleted).FirstOrDefaultAsync(); } public virtual Task> FindAsync(Expression> predicate, bool filterDeleted = true) where TFind : class { return FindAsISugarQueryable(predicate, filterDeleted).ToListAsync(); } public virtual Task> FindAsync(Expression> predicate, bool filterDeleted = true) { return FindAsISugarQueryable(predicate, filterDeleted).ToListAsync(); } public virtual Task FindFirstAsync(Expression> predicate, bool filterDeleted = true) { return FindAsISugarQueryable(predicate, filterDeleted).FirstOrDefaultAsync(); } public virtual Task> FindAsync(Expression> predicate, Expression> selector, bool filterDeleted = true) { return FindAsISugarQueryable(predicate, filterDeleted).Select(selector).ToListAsync(); } public virtual Task FindFirstAsync(Expression> predicate, Expression> selector, bool filterDeleted = true) { return FindAsISugarQueryable(predicate, filterDeleted).Select(selector).FirstOrDefaultAsync(); } private ISugarQueryable FindAsISugarQueryable(Expression> predicate, bool filterDeleted = true) where TFind : class { return VOLContext.Set(filterDeleted).Where(predicate); } public virtual List Find(Expression> predicate, Expression> selector, bool filterDeleted = true) { return VOLContext.Set(filterDeleted).Where(predicate).Select(selector).ToList(); } /// /// 单表查询 /// /// /// public virtual List Find(Expression> predicate, bool filterDeleted = true) { return FindAsISugarQueryable(predicate, filterDeleted).ToList(); } /// /// /// /// /// /// 排序字段 /// public virtual TEntity FindFirst(Expression> predicate, bool filterDeleted = true) { return VOLContext.Set(filterDeleted).Where(predicate).FirstOrDefault(); } public ISugarQueryable FindAsIQueryable(Expression> predicate, Expression>> orderBy = null) { //if (orderBy != null) // return DbContext.Set().Where(predicate).GetISugarQueryableOrderBy(orderBy.GetExpressionToDic()); return DbContext.Set().Where(predicate); } public ISugarQueryable Include(Expression> incluedProperty) { return DbContext.Set().Includes(incluedProperty); } /// /// 通过条件查询返回指定列的数据(将TEntity映射到匿名或实体T) ///var result = Sys_UserRepository.GetInstance.Find(x => x.UserName == loginInfo.userName, p => new { uname = p.UserName }); /// /// /// /// /// /// /// /// 查询条件 /// 多个排序字段key为字段,value为升序/降序 /// public virtual ISugarQueryable IQueryablePage(int pageIndex, int pagesize, out int rowcount, Expression> predicate, Expression>> orderBy, bool returnRowCount = true) where TFind : class { pageIndex = pageIndex <= 0 ? 1 : pageIndex; pagesize = pagesize <= 0 ? 10 : pagesize; if (predicate == null) { predicate = x => 1 == 1; } var _db = DbContext.Set(); rowcount = returnRowCount ? _db.Count(predicate) : 0; return DbContext.Set().Where(predicate) .GetISugarQueryableOrderBy(orderBy.GetExpressionToDic()) .Skip((pageIndex - 1) * pagesize) .Take(pagesize); } /// /// 分页排序 /// /// /// /// /// /// /// public virtual ISugarQueryable IQueryablePage(ISugarQueryable queryable, int pageIndex, int pagesize, out int rowcount, Dictionary orderBy, bool returnRowCount = true) { pageIndex = pageIndex <= 0 ? 1 : pageIndex; pagesize = pagesize <= 0 ? 10 : pagesize; rowcount = returnRowCount ? queryable.Count() : 0; return queryable.GetISugarQueryableOrderBy(orderBy) .Skip((pageIndex - 1) * pagesize) .Take(pagesize); } /// /// 更新表数据 /// /// /// 是否保存 /// 格式 Expression> expTree = x => new { x.字段1, x.字段2 }; public virtual int Update(TEntity entity, Expression> properties, bool saveChanges = false) { return Update(entity, properties, saveChanges); } public virtual int Update(TSource entity, Expression> properties, bool saveChanges = false) where TSource : class, new() { return UpdateRange(new List { entity }, properties, saveChanges); } public virtual int Update(TSource entity, string[] properties, bool saveChanges = false) where TSource : class, new() { return UpdateRange(new List() { entity }, properties, saveChanges); } public virtual int Update(TSource entity, bool saveChanges = false) where TSource : class, new() { return UpdateRange(new List() { entity }, new string[0], saveChanges); } public virtual int UpdateRange(IEnumerable entities, Expression> properties, bool saveChanges = false) where TSource : class, new() { return UpdateRange(entities, properties?.GetExpressionProperty(), saveChanges); } public virtual int UpdateRange(IEnumerable entities, bool saveChanges = false) where TSource : class, new() { return UpdateRange(entities, new string[0], saveChanges); } /// /// 更新表数据 /// /// /// 格式 Expression> expTree = x => new { x.字段1, x.字段2 }; public int UpdateRange(IEnumerable entities, string[] properties, bool saveChanges = false) where TSource : class, new() { return DbContext.UpdateRange(entities, properties, saveChanges); } /// /// /// /// /// 是否修改明细 /// 是否删除明细不存在的数据 /// 主表指定修改字段 /// 明细指定修改字段 /// 是否保存 /// public virtual WebResponseContent UpdateRange(TEntity entity, bool updateDetail = false, bool delNotExist = false, Expression> updateMainFields = null, Expression> updateDetailFields = null, bool saveChange = false) where Detail : class, new() { WebResponseContent webResponse = new WebResponseContent(); Update(entity, updateMainFields); string message = ""; if (updateDetail) { PropertyInfo[] properties = typeof(TEntity).GetProperties(); PropertyInfo detail = properties.Where(x => x.PropertyType.Name == "List`1").ToList().FirstOrDefault(); if (detail != null) { PropertyInfo key = properties.GetKeyProperty(); object obj = detail.GetValue(entity); Type detailType = typeof(TEntity).GetCustomAttribute().DetailTable[0]; message = UpdateDetail(obj as List, key.Name, key.GetValue(entity), updateDetailFields, delNotExist); } } if (!saveChange) return webResponse.OK(); DbContext.SaveChanges(); return webResponse.OK("修改成功,明细" + message, entity); } private string UpdateDetail(List list, string keyName, object keyValue, Expression> updateDetailFields = null, bool delNotExist = false) where TDetail : class, new() { if (list == null) return ""; PropertyInfo property = typeof(TDetail).GetKeyProperty(); string detailKeyName = property.Name; var details = DbContext.Set(); Expression> selectExpression = detailKeyName.GetExpression(); Expression> whereExpression = keyName.CreateExpression(keyValue, LinqExpressionType.Equal); //这里有问题, Expression>会转换为查询所有字段20231020 //List detailKeys = details.Where(whereExpression).Select(selectExpression).ToList(); List detailKeys = details.Where(whereExpression).ToList().Select(selectExpression.Compile()).ToList(); //获取主键默认值 string keyDefaultVal = property.PropertyType .Assembly .CreateInstance(property.PropertyType.FullName).ToString(); int addCount = 0; int editCount = 0; int delCount = 0; PropertyInfo mainKeyProperty = typeof(TDetail).GetProperty(keyName); List keys = new List(); list.ForEach(x => { var set = DbContext.Set(); object val = property.GetValue(x); //主键是默认值的为新增的数据 if (val.ToString() == keyDefaultVal) { x.SetCreateDefaultVal(); //设置主表的值,也可以不设置 mainKeyProperty.SetValue(x, keyValue); DbContext.Insertable(x).AddQueue(); addCount++; } else//修改的数据 { //获取所有修改的key,如果从数据库查来的key,不在修改中的key,则为删除的数据 keys.Add(val); x.SetModifyDefaultVal(); Update(x, updateDetailFields); // repository.DbContext.Entry(x).State = EntityState.Modified; editCount++; } }); //删除 if (delNotExist) { detailKeys.Where(x => !keys.Contains(x)).ToList().ForEach(d => { delCount++; TDetail detail = Activator.CreateInstance(); property.SetValue(detail, d); DbContext.Deleteable(detail).AddQueue(); for (int i = 0; i < list.Count(); i++) { if (property.GetValue(list[i]) == d) { list.RemoveAt(i); } } }); } return $"修改[{editCount}]条,新增[{addCount}]条,删除[{delCount}]条"; } public virtual void Delete(TEntity model, bool saveChanges = false) { DbContext.Deleteable(model).AddQueue(); if (saveChanges) { DbContext.SaveChanges(); } } public virtual void Delete(T model, bool saveChanges) where T : class, new() { DbContext.Deleteable(model).AddQueue(); if (saveChanges) { DbContext.SaveChanges(); } } /// /// 通过主键批量删除 /// /// 主键key /// 是否连明细一起删除 /// public virtual int DeleteWithKeys(object[] keys, bool saveChange = false) { var keyPro = typeof(TEntity).GetKeyProperty(); foreach (var key in keys.Distinct()) { TEntity entity = Activator.CreateInstance(); keyPro.SetValue(entity, key.ChangeType(keyPro.PropertyType)); DbContext.Deleteable(entity).AddQueue(); // DbContext.Entry(entity).State = EntityState.Deleted; } if (saveChange) { DbContext.SaveChanges(); } return keys.Length; } /// /// 写入数据并设置自增 /// /// public virtual void AddWithSetIdentity(TEntity entity) { //var keyProperty = typeof(TEntity).GetKeyProperty(); //int id = DbContext.Insertable(entity).ExecuteReturnIdentity(); //keyProperty.SetValue(id, entity); DbContext.Insertable(entity).ExecuteReturnEntity(); } public virtual void AddWithSetIdentity(T entity) where T : class, new() { DbContext.Insertable(entity).ExecuteReturnEntity(); } public virtual void Add(TEntity entities, bool saveChanges = false) { AddRange(new List() { entities }, saveChanges); } public virtual void Add(T entities, bool saveChanges = false) where T : class, new() { DbContext.Insertable(entities).AddQueue(); if (saveChanges) DbContext.SaveChanges(); } public virtual void AddRange(List entities, bool saveChanges = false) { DbContext.Insertable(entities).AddQueue(); //DbContext.Insertable(entities).ExecuteReturnIdentity(); if (saveChanges) DbContext.SaveChanges(); } public virtual void AddRange(List entities, bool saveChanges = false) where T : class, new() { DbContext.Insertable(entities).AddQueue(); if (saveChanges) DbContext.SaveChanges(); } public virtual int SaveChanges() { return VOLContext.SaveChanges(); } public virtual Task SaveChangesAsync() { return VOLContext.SqlSugarClient.SaveChangesAsync(); } public virtual int ExecuteSqlCommand(string sql, params SugarParameter[] SugarParameters) { return DbContext.Ado.ExecuteCommand(sql, SugarParameters); // return DbContext.Database.ExecuteSqlRaw(sql, SugarParameters); } public virtual List FromSql(string sql, params SugarParameter[] SugarParameters) { return DbContext.Ado.SqlQuery(sql, SugarParameters).ToList(); } /// /// 执行sql /// 使用方式 FormattableString sql=$"select * from xx where name ={xx} and pwd={xx1} ", /// FromSqlInterpolated内部处理sql注入的问题,直接在{xx}写对应的值即可 /// 注意:sql必须 select * 返回所有TEntity字段, /// /// /// //public virtual ISugarQueryable FromSqlInterpolated([NotNull] FormattableString sql) //{ // //DBSet.FromSqlInterpolated(sql).Select(x => new { x,xxx}).ToList(); // return DbContext.Ado.SqlQuery(sql); //} /// /// 取消上下文跟踪 /// /// public virtual void Detached(TEntity entity) { // DbContext.Entry(entity).State = EntityState.Detached; } public virtual void DetachedRange(IEnumerable entities) { //foreach (var entity in entities) //{ // DbContext.Entry(entity).State = EntityState.Detached; //} } } }