You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

409 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.Reflection;
using Common.Const;
using Entity.Base;
using Entity.Dto.Req;
using Mapster;
using MapsterMapper;
using SqlSugar;
namespace Repository
{
public static class RepositoryExtension
{
/// <summary>
/// 实体假删除 _rep.FakeDelete(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="repository"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static int FakeDelete<T>(this ISugarRepository repository, T entity) where T : EntityBase, new()
{
return repository.Context.FakeDelete(entity);
}
/// <summary>
/// 实体假删除 db.FakeDelete(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static int FakeDelete<T>(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();
}
/// <summary>
/// 实体集合批量假删除 _rep.FakeDelete(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="repository"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static int FakeDelete<T>(this ISugarRepository repository, List<T> entity) where T : EntityBase, new()
{
return repository.Context.FakeDelete(entity);
}
/// <summary>
/// 实体集合批量假删除 db.FakeDelete(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static int FakeDelete<T>(this ISqlSugarClient db, List<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();
}
/// <summary>
/// 实体假删除异步 _rep.FakeDeleteAsync(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="repository"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static Task<int> FakeDeleteAsync<T>(this ISugarRepository repository, T entity) where T : EntityBase, new()
{
return repository.Context.FakeDeleteAsync(entity);
}
/// <summary>
/// 实体假删除 db.FakeDelete(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static Task<int> FakeDeleteAsync<T>(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();
}
/// <summary>
/// 实体集合批量假删除异步 _rep.FakeDeleteAsync(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="repository"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static Task<int> FakeDeleteAsync<T>(this ISugarRepository repository, List<T> entity) where T : EntityBase, new()
{
return repository.Context.FakeDeleteAsync(entity);
}
/// <summary>
/// 实体集合批量假删除 db.FakeDelete(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static Task<int> FakeDeleteAsync<T>(this ISqlSugarClient db, List<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();
}
/// <summary>
/// 排序方式(默认降序)
/// </summary>
/// <param name="queryable"></param>
/// <param name="pageInput"> </param>
/// <param name="prefix"> </param>
/// <param name="defaultSortField"> 默认排序字段 </param>
/// <param name="descSort"> 是否降序 </param>
/// <returns> </returns>
public static ISugarQueryable<T> OrderBuilder<T>(this ISugarQueryable<T> queryable, BasePageReq pageInput, string prefix = "", string defaultSortField = "Id", bool descSort = true)
{
// 约定默认每张表都有Id排序
var orderStr = string.IsNullOrWhiteSpace(defaultSortField) ? "" : $"{prefix}{defaultSortField}" + (descSort ? " Desc" : " Asc");
TypeAdapterConfig typeAdapterConfig = new();
typeAdapterConfig.ForType<T, BasePageReq>().IgnoreNullValues(true);
Mapper mapper = new(typeAdapterConfig); // 务必将mapper设为单实例
var nowPagerInput = mapper.Map<BasePageReq>(pageInput);
// 排序是否可用-排序字段和排序顺序都为非空才启用排序
if (!string.IsNullOrEmpty(nowPagerInput.Field) && !string.IsNullOrEmpty(nowPagerInput.OrderDirection))
{
var col = queryable.Context.EntityMaintenance.GetEntityInfo<T>().Columns.FirstOrDefault(u => u.PropertyName.Equals(nowPagerInput.Field, StringComparison.CurrentCultureIgnoreCase));
orderStr = col != null
? $"{prefix}{col.DbColumnName} {(nowPagerInput.OrderDirection == nowPagerInput.DescStr ? "Desc" : "Asc")}"
: $"{prefix}{nowPagerInput.Field} {(nowPagerInput.OrderDirection == nowPagerInput.DescStr ? "Desc" : "Asc")}";
}
return queryable.OrderByIF(!string.IsNullOrWhiteSpace(orderStr), orderStr);
}
/// <summary>
/// 更新实体并记录差异日志 _rep.UpdateWithDiffLog(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="repository"></param>
/// <param name="entity"></param>
/// <param name="ignoreAllNullColumns"></param>
/// <returns></returns>
public static int UpdateWithDiffLog<T>(this ISugarRepository repository, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new()
{
return repository.Context.UpdateWithDiffLog(entity, ignoreAllNullColumns);
}
/// <summary>
/// 更新实体并记录差异日志 _rep.UpdateWithDiffLog(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="entity"></param>
/// <param name="ignoreAllNullColumns"></param>
/// <returns></returns>
public static int UpdateWithDiffLog<T>(this ISqlSugarClient db, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new()
{
return db.Updateable(entity).AS()
.IgnoreColumns(ignoreAllNullColumns: ignoreAllNullColumns)
.EnableDiffLogEvent()
.ExecuteCommand();
}
/// <summary>
/// 更新实体并记录差异日志 _rep.UpdateWithDiffLogAsync(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="repository"></param>
/// <param name="entity"></param>
/// <param name="ignoreAllNullColumns"></param>
/// <returns></returns>
public static Task<int> UpdateWithDiffLogAsync<T>(this ISugarRepository repository, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new()
{
return repository.Context.UpdateWithDiffLogAsync(entity, ignoreAllNullColumns);
}
/// <summary>
/// 更新实体并记录差异日志 _rep.UpdateWithDiffLogAsync(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="entity"></param>
/// <param name="ignoreAllNullColumns"></param>
/// <returns></returns>
public static Task<int> UpdateWithDiffLogAsync<T>(this ISqlSugarClient db, T entity, bool ignoreAllNullColumns = true) where T : EntityBase, new()
{
return db.Updateable(entity)
.IgnoreColumns(ignoreAllNullColumns: ignoreAllNullColumns)
.EnableDiffLogEvent()
.ExecuteCommandAsync();
}
/// <summary>
/// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="repository"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static int InsertWithDiffLog<T>(this ISugarRepository repository, T entity) where T : EntityBase, new()
{
return repository.Context.InsertWithDiffLog(entity);
}
/// <summary>
/// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static int InsertWithDiffLog<T>(this ISqlSugarClient db, T entity) where T : EntityBase, new()
{
return db.Insertable(entity).AS().EnableDiffLogEvent().ExecuteCommand();
}
/// <summary>
/// 新增实体并记录差异日志 _rep.InsertWithDiffLogAsync(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="repository"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static Task<int> InsertWithDiffLogAsync<T>(this ISugarRepository repository, T entity) where T : EntityBase, new()
{
return repository.Context.InsertWithDiffLogAsync(entity);
}
/// <summary>
/// 新增实体并记录差异日志 _rep.InsertWithDiffLog(entity)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="db"></param>
/// <param name="entity"></param>
/// <returns></returns>
public static Task<int> InsertWithDiffLogAsync<T>(this ISqlSugarClient db, T entity) where T : EntityBase, new()
{
return db.Insertable(entity).AS().EnableDiffLogEvent().ExecuteCommandAsync();
}
/// <summary>
/// 多库查询
/// </summary>
/// <param name="queryable"></param>
/// <returns> </returns>
public static ISugarQueryable<T> AS<T>(this ISugarQueryable<T> queryable)
{
var info = GetTableInfo<T>();
return queryable.AS<T>($"{info.Item1}.{info.Item2}");
}
/// <summary>
/// 多库查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T2"></typeparam>
/// <param name="queryable"></param>
/// <returns></returns>
public static ISugarQueryable<T, T2> AS<T, T2>(this ISugarQueryable<T, T2> queryable)
{
var info = GetTableInfo<T2>();
return queryable.AS<T2>($"{info.Item1}.{info.Item2}");
}
/// <summary>
/// 多库更新
/// </summary>
/// <param name="updateable"></param>
/// <returns> </returns>
public static IUpdateable<T> AS<T>(this IUpdateable<T> updateable) where T : EntityBase, new()
{
var info = GetTableInfo<T>();
return updateable.AS($"{info.Item1}.{info.Item2}");
}
/// <summary>
/// 多库新增
/// </summary>
/// <param name="insertable"></param>
/// <returns> </returns>
public static IInsertable<T> AS<T>(this IInsertable<T> insertable) where T : EntityBase, new()
{
var info = GetTableInfo<T>();
return insertable.AS($"{info.Item1}.{info.Item2}");
}
/// <summary>
/// 多库删除
/// </summary>
/// <param name="deleteable"></param>
/// <returns> </returns>
public static IDeleteable<T> AS<T>(this IDeleteable<T> deleteable) where T : EntityBase, new()
{
var info = GetTableInfo<T>();
return deleteable.AS($"{info.Item1}.{info.Item2}");
}
/// <summary>
/// 根据实体类型获取表信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
private static Tuple<string, string> GetTableInfo<T>()
{
var entityType = typeof(T);
var attr = entityType.GetCustomAttribute<TenantAttribute>();
var configId = attr == null ? SqlSugarConst.MainConfigId : attr.configId.ToString();
var tableName = entityType.GetCustomAttribute<SugarTable>().TableName;
return new Tuple<string, string>(configId, tableName);
}
/// <summary>
/// 禁用过滤器-适用于更新和删除操作(只对当前请求有效,禁止使用异步)
/// </summary>
/// <param name="repository"></param>
/// <param name="action">禁止异步</param>
/// <returns></returns>
public static void RunWithoutFilter(this ISugarRepository repository, Action action)
{
repository.Context.QueryFilter.ClearAndBackup(); // 清空并备份过滤器
action.Invoke();
repository.Context.QueryFilter.Restore(); // 还原过滤器
// 用例
//_rep.RunWithoutFilter(() =>
//{
// 执行更新或者删除
// 禁止使用异步函数
//});
}
/// <summary>
/// 忽略租户
/// </summary>
/// <param name="queryable"></param>
/// <param name="ignore">是否忽略 默认true</param>
/// <returns> </returns>
public static ISugarQueryable<T> IgnoreTenant<T>(this ISugarQueryable<T> queryable, bool ignore = true)
{
return ignore ? queryable.ClearFilter<ITenantIdFilter>() : queryable;
}
/// <summary>
/// 导航+子表过滤 创建一个扩展函数默认是Class不支持Where
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="thisValue"></param>
/// <param name="whereExpression"></param>
/// <returns></returns>
public static List<T> Where<T>(this T thisValue, Func<T, bool> whereExpression) where T : class, new()
{
return new List<T>() { thisValue };
}
/// <summary>
/// 导航+子表过滤 创建一个扩展函数默认是Class不支持WhereIF
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="thisValue"></param>
/// <param name="isWhere"></param>
/// <param name="whereExpression"></param>
/// <returns></returns>
public static List<T> WhereIF<T>(this T thisValue, bool isWhere, Func<T, bool> whereExpression) where T : class, new()
{
return new List<T>() { thisValue };
}
/// <summary>
/// 只更新某些列
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="R"></typeparam>
/// <param name="updateable"></param>
/// <returns></returns>
public static IUpdateable<T> OnlyUpdateColumn<T, R>(this IUpdateable<T> updateable) where T : EntityBase, new() where R : class, new()
{
if (updateable.UpdateBuilder.UpdateColumns == null)
updateable.UpdateBuilder.UpdateColumns = new List<string>();
foreach (PropertyInfo info in typeof(R).GetProperties())
{
// 判断是否是相同属性
if (typeof(T).GetProperty(info.Name) != null)
updateable.UpdateBuilder.UpdateColumns.Add(info.Name);
}
return updateable;
}
}
}