// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! using MapsterMapper; namespace Admin.NET.Core; /// /// 仓储扩展方法 /// public static class RepositoryExtension { /// /// 实体假删除 _rep.FakeDelete(entity) /// /// /// /// /// public static int FakeDelete(this ISugarRepository repository, T entity) where T : EntityBase, new() { return repository.Context.FakeDelete(entity); } /// /// 实体假删除 db.FakeDelete(entity) /// /// /// /// /// public static int FakeDelete(this ISqlSugarClient db, T entity) where T : EntityBase, new() { return db.Updateable(entity).AS().ReSetValue(x => { x.IsDelete = true; }) .IgnoreColumns(ignoreAllNullColumns: true) .EnableDiffLogEvent() // 记录差异日志 .UpdateColumns(x => new { x.IsDelete, x.UpdateTime, x.UpdateUserId }) // 允许更新的字段-AOP拦截自动设置UpdateTime、UpdateUserId .ExecuteCommand(); } /// /// 实体集合批量假删除 _rep.FakeDelete(entity) /// /// /// /// /// public static int FakeDelete(this ISugarRepository repository, List entity) where T : EntityBase, new() { return repository.Context.FakeDelete(entity); } /// /// 实体集合批量假删除 db.FakeDelete(entity) /// /// /// /// /// public static int FakeDelete(this ISqlSugarClient db, List entity) where T : EntityBase, new() { return db.Updateable(entity).AS().ReSetValue(x => { x.IsDelete = true; }) .IgnoreColumns(ignoreAllNullColumns: true) .EnableDiffLogEvent() // 记录差异日志 .UpdateColumns(x => new { x.IsDelete, x.UpdateTime, x.UpdateUserId }) // 允许更新的字段-AOP拦截自动设置UpdateTime、UpdateUserId .ExecuteCommand(); } /// /// 实体假删除异步 _rep.FakeDeleteAsync(entity) /// /// /// /// /// public static Task FakeDeleteAsync(this ISugarRepository repository, T entity) where T : EntityBase, new() { return repository.Context.FakeDeleteAsync(entity); } /// /// 实体假删除 db.FakeDelete(entity) /// /// /// /// /// public static Task FakeDeleteAsync(this ISqlSugarClient db, T entity) where T : EntityBase, new() { return db.Updateable(entity).AS().ReSetValue(x => { x.IsDelete = true; }) .IgnoreColumns(ignoreAllNullColumns: true) .EnableDiffLogEvent() // 记录差异日志 .UpdateColumns(x => new { x.IsDelete, x.UpdateTime, x.UpdateUserId }) // 允许更新的字段-AOP拦截自动设置UpdateTime、UpdateUserId .ExecuteCommandAsync(); } /// /// 实体集合批量假删除异步 _rep.FakeDeleteAsync(entity) /// /// /// /// /// public static Task FakeDeleteAsync(this ISugarRepository repository, List entity) where T : EntityBase, new() { return repository.Context.FakeDeleteAsync(entity); } /// /// 实体集合批量假删除 db.FakeDelete(entity) /// /// /// /// /// public static Task FakeDeleteAsync(this ISqlSugarClient db, List entity) where T : EntityBase, new() { return db.Updateable(entity).AS().ReSetValue(x => { x.IsDelete = true; }) .IgnoreColumns(ignoreAllNullColumns: true) .EnableDiffLogEvent() // 记录差异日志 .UpdateColumns(x => new { x.IsDelete, x.UpdateTime, x.UpdateUserId }) // 允许更新的字段-AOP拦截自动设置UpdateTime、UpdateUserId .ExecuteCommandAsync(); } /// /// 排序方式(默认降序) /// /// /// /// /// 默认排序字段 /// 是否降序 /// public static ISugarQueryable OrderBuilder(this ISugarQueryable queryable, BasePageInput pageInput, string prefix = "", string defaultSortField = "Id", bool descSort = true) { var iSqlBuilder = InstanceFactory.GetSqlBuilderWithContext(queryable.Context); // 约定默认每张表都有Id排序 var orderStr = string.IsNullOrWhiteSpace(defaultSortField) ? "" : $"{prefix}{iSqlBuilder.GetTranslationColumnName(defaultSortField)}" + (descSort ? " Desc" : " Asc"); TypeAdapterConfig typeAdapterConfig = new(); typeAdapterConfig.ForType().IgnoreNullValues(true); Mapper mapper = new(typeAdapterConfig); // 务必将mapper设为单实例 var nowPagerInput = mapper.Map(pageInput); // 排序是否可用-排序字段为非空才启用排序,排序顺序默认为倒序 if (!string.IsNullOrEmpty(nowPagerInput.Field)) { nowPagerInput.Field = Regex.Replace(nowPagerInput.Field, @"[\s;()\-'@=/%]", ""); //过滤掉一些关键字符防止构造特殊SQL语句注入 var orderByDbName = queryable.Context.EntityMaintenance.GetDbColumnName(nowPagerInput.Field);//防止注入,类中只要不存在属性名就会报错 orderStr = $"{prefix}{iSqlBuilder.GetTranslationColumnName(orderByDbName)} {(string.IsNullOrEmpty(nowPagerInput.Order) || nowPagerInput.Order.Equals(nowPagerInput.DescStr, StringComparison.OrdinalIgnoreCase) ? "Desc" : "Asc")}"; } return queryable.OrderByIF(!string.IsNullOrWhiteSpace(orderStr), orderStr); } /// /// 更新实体并记录差异日志 _rep.UpdateWithDiffLog(entity) /// /// /// /// /// /// public static int UpdateWithDiffLog(this ISugarRepository repository, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new() { return repository.Context.UpdateWithDiffLog(entity, ignoreAllNullColumns); } /// /// 更新实体并记录差异日志 _rep.UpdateWithDiffLog(entity) /// /// /// /// /// /// public static int UpdateWithDiffLog(this ISqlSugarClient db, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new() { return db.Updateable(entity).AS() .IgnoreColumns(ignoreAllNullColumns: ignoreAllNullColumns) .EnableDiffLogEvent() .ExecuteCommand(); } /// /// 更新实体并记录差异日志 _rep.UpdateWithDiffLogAsync(entity) /// /// /// /// /// /// public static Task UpdateWithDiffLogAsync(this ISugarRepository repository, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new() { return repository.Context.UpdateWithDiffLogAsync(entity, ignoreAllNullColumns); } /// /// 更新实体并记录差异日志 _rep.UpdateWithDiffLogAsync(entity) /// /// /// /// /// /// public static Task UpdateWithDiffLogAsync(this ISqlSugarClient db, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new() { return db.Updateable(entity) .IgnoreColumns(ignoreAllNullColumns: ignoreAllNullColumns) .EnableDiffLogEvent() .ExecuteCommandAsync(); } /// /// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity) /// /// /// /// /// public static int InsertWithDiffLog(this ISugarRepository repository, T entity) where T : EntityBase, new() { return repository.Context.InsertWithDiffLog(entity); } /// /// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity) /// /// /// /// /// public static int InsertWithDiffLog(this ISqlSugarClient db, T entity) where T : EntityBase, new() { return db.Insertable(entity).AS().EnableDiffLogEvent().ExecuteCommand(); } /// /// 新增实体并记录差异日志 _rep.InsertWithDiffLogAsync(entity) /// /// /// /// /// public static Task InsertWithDiffLogAsync(this ISugarRepository repository, T entity) where T : EntityBase, new() { return repository.Context.InsertWithDiffLogAsync(entity); } /// /// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity) /// /// /// /// /// public static Task InsertWithDiffLogAsync(this ISqlSugarClient db, T entity) where T : EntityBase, new() { return db.Insertable(entity).AS().EnableDiffLogEvent().ExecuteCommandAsync(); } /// /// 多库查询 /// /// /// public static ISugarQueryable AS(this ISugarQueryable queryable) { var info = GetTableInfo(); return queryable.AS($"{info.Item1}.{info.Item2}"); } /// /// 多库查询 /// /// /// /// /// public static ISugarQueryable AS(this ISugarQueryable queryable) { var info = GetTableInfo(); return queryable.AS($"{info.Item1}.{info.Item2}"); } /// /// 多库更新 /// /// /// public static IUpdateable AS(this IUpdateable updateable) where T : EntityBase, new() { var info = GetTableInfo(); return updateable.AS($"{info.Item1}.{info.Item2}"); } /// /// 多库新增 /// /// /// public static IInsertable AS(this IInsertable insertable) where T : EntityBase, new() { var info = GetTableInfo(); return insertable.AS($"{info.Item1}.{info.Item2}"); } /// /// 多库删除 /// /// /// public static IDeleteable AS(this IDeleteable deleteable) where T : EntityBase, new() { var info = GetTableInfo(); return deleteable.AS($"{info.Item1}.{info.Item2}"); } /// /// 根据实体类型获取表信息 /// /// /// private static Tuple GetTableInfo() { var entityType = typeof(T); var attr = entityType.GetCustomAttribute(); var configId = attr == null ? SqlSugarConst.MainConfigId : attr.configId.ToString(); var tableName = entityType.GetCustomAttribute().TableName; return new Tuple(configId, tableName); } /// /// 禁用过滤运行,适用于更新和删除 /// /// repository /// /// public static async Task RunWithoutFilter(this ISugarRepository repository, Func action) { await repository.Context.RunWithoutFilter(action); // 用例 //await _rep.RunWithoutFilter(async () => //{ // // 执行数据库操作 // await _rep.AsQueryable().ToListAsync(); //}); } /// /// 禁用过滤运行,适用于更新和删除 /// /// db /// /// public static async Task RunWithoutFilter(this ISqlSugarClient client, Func action) { var db = client.CopyNew(); // 清空并还原 ,不会影响其他请求,只是当前请求清空 db.QueryFilter.ClearAndBackup();//清空并备份过滤器 await action.Invoke(); db.QueryFilter.Restore();//还原过滤器 // 用例 //await _db.RunWithoutFilter(async () => //{ // // 执行数据库操作 // await _db.Queryable().ToListAsync(); //}); } ///// ///// 忽略租户 ///// ///// ///// 是否忽略 默认true ///// //public static ISugarQueryable IgnoreTenant(this ISugarQueryable queryable, bool ignore = true) //{ // return ignore ? queryable.ClearFilter() : queryable; //} /// /// 只更新某些列 /// /// /// /// /// public static IUpdateable OnlyUpdateColumn(this IUpdateable updateable) where T : EntityBase, new() where R : class, new() { if (updateable.UpdateBuilder.UpdateColumns == null) updateable.UpdateBuilder.UpdateColumns = []; foreach (PropertyInfo info in typeof(R).GetProperties()) { // 判断是否是相同属性 if (typeof(T).GetProperty(info.Name) != null) updateable.UpdateBuilder.UpdateColumns.Add(info.Name); } return updateable; } /// /// 批量列表in查询 /// /// /// /// /// /// /// /// public static async Task> BulkListQuery(this ISugarQueryable queryable, Expression, bool>> exp, IEnumerable queryList, CancellationToken stoppingToken) where T1 : class, new() { // 创建临时表 (用真表兼容性好,表名随机) var tableName = "Temp" + SnowFlakeSingle.Instance.NextId(); try { var type = queryable.Context.DynamicBuilder().CreateClass(tableName, new SugarTable()) .CreateProperty("ColumnName", typeof(string), new SugarColumn() { IsPrimaryKey = true, ColumnName = "columnName" }) // 主键不要自增 .BuilderType(); // 创建表 queryable.Context.CodeFirst.InitTables(type); var insertData = queryList.Select(it => new SingleColumnEntity() { ColumnName = it }).ToList(); // 插入临时表 queryable.Context.Fastest>() .AS(tableName) .BulkCopy(insertData); var queryTemp = queryable.Context.Queryable>() .AS(tableName); var systemData = await queryable .InnerJoin(queryTemp, exp) .ToListAsync(stoppingToken); queryable.Context.DbMaintenance.DropTable(tableName); return systemData; } catch (Exception error) { queryable.Context.DbMaintenance.DropTable(tableName); throw Oops.Oh(error); } } }