JKFZJCXT/BZPT.SqlSugarRepository/RepositoryBase.cs

496 lines
17 KiB
C#
Raw Permalink Normal View History

2025-07-17 09:35:54 +08:00
/***********************************************************
**:
**:
** :
** : 1.0
** 2015/12/7 16:06:56
**
************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SqlSugar;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using System.Text;
using NPlatform.Infrastructure.IdGenerators;
using NPlatform.Filters;
using System.DirectoryServices;
using DevExtreme.AspNet.Data;
namespace BZPT.Repositories
{
/// <summary>
/// 聚合仓储基类
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <typeparam name="string">主键类型</typeparam>
public abstract class RepositoryBase<TEntity> : ResultHelper, IRepository<TEntity, string>, IRepositorySugarBase<TEntity, string> where TEntity : EntityBase<string>, new()
{
[Autowired]
public ILogger<RepositoryBase<TEntity>> loggerSvc { get; set; }
[Autowired]
public IHttpContextAccessor httpContextAccessor { get; set; }
protected IRepositoryOptions Options;
/// <summary>
/// 数据库连接承载对象,默认注入基础库,管理所有的租户连接。
/// </summary>
protected DBContext ContextManage;
// 构造函数
public RepositoryBase(DBContext dbContext)
{
ContextManage = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
}
public string? GetUserId()
{
return httpContextAccessor.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
}
public string? GetUserName()
{
return httpContextAccessor.HttpContext?.User?.Identity?.Name;
}
public ISqlSugarClient DbDefault
{
get
{
return ContextManage;
}
}
/// <summary>
/// 获取业务库对象
/// </summary>
public ISqlSugarClient Db
{
get
{
var tenantId = httpContextAccessor.HttpContext?.User?.Claims?.Where(t => t.Type.ToUpper() =="TENANTID").FirstOrDefault()?.Value;
var connection = ContextManage.GetConnection("default");
if (!string.IsNullOrWhiteSpace(tenantId))
{
var tenant = ContextManage.GetConnection("default").Queryable<BZPT.Domains.Entity.Sys.Tenant>().Where(t => t.Id == tenantId).First();
var configId = tenantId;//集团ID也可以叫租户ID
if (!ContextManage.IsAnyConnection(configId))
{ //用非默认ConfigId进行测试
//添加业务库只在当前上下文有效原理SqlSugarScope模式入门文档去看
ContextManage.AddConnection(new ConnectionConfig()
{
ConfigId = configId,
ConnectionString = tenant.ConnectionString,
DbType = Enum.Parse<DbType>(tenant.DbType, true),
IsAutoCloseConnection = true
});
}
//原理说明
//IsAnyConnection、AddConnection和GetConnection 都是Scope周期不同请求不会有影响
connection = ContextManage.GetConnection(configId);
//可以给业务库result设置AOP和过滤滤器
}
// connection.QueryFilter.AddTableFilter<ILogicDelete>(it => it.IsDeleted == false);
//// 应用过滤器
//foreach (var ft in this.Options.QueryFilters)
//{
// var exp = ft.Value.GetFilter<TEntity>();
// if (exp != null)
// {
// connection.QueryFilter.AddTableFilter<TEntity>(exp);
// }
//}
return connection;
}
}
public TEntity this[string key]
{
get
{
if (EqualityComparer<string>.Default.Equals(key, default(string)))
{
return default(TEntity);
}
return this.Db.Queryable<TEntity>().Where(t => t.Id != null && t.Id.Equals(key)).First();
}
set
{
if (value is null)
{
throw new ArgumentNullException(nameof(value));
}
//功能写法可以将插入和更新拆开,然后调用插入和更新独有特性
var x = Db.Storageable(value).ToStorage();
var rst = x.AsInsertable.ExecuteCommand();//不存在插入
var rst2 = x.AsUpdateable.ExecuteCommand();//存在更新
}
}
/// <summary>
/// Initializes a new instance of the <see cref="RepositoryBase{TEntity,string}"/> class.
/// 仓储基类
/// </summary>
/// <param name="option">
/// 仓储配置
/// </param>
public RepositoryBase(IRepositoryOptions option, DBContext dbContext)
{
Options = option;
ContextManage = dbContext;
}
#region
/// <summary>
/// 异步新增
/// </summary>
/// <param name="items">新增对象的集合</param>
/// <returns><placeholder>A <see cref="Task"/> representing the asynchronous operation.</placeholder></returns>
public async virtual Task<int> AddsAsync(params TEntity[] items)
{
if (items is null)
{
throw new ArgumentNullException(nameof(items));
}
foreach(var item in items)
{
if(string.IsNullOrWhiteSpace(item.Id))
item.Id= StringObjectIdGenerator.Instance.GenerateId().ToString();
}
return await this.Db.Insertable<TEntity>(items).ExecuteCommandAsync();
}
/// <summary>
/// 异步新增
/// </summary>
/// <param name="items">新增对象的集合</param>
/// <returns><placeholder>A <see cref="Task"/> representing the asynchronous operation.</placeholder></returns>
public async virtual Task<int> AddOrUpdate(TEntity item)
{
if (item is null)
{
throw new ArgumentNullException(nameof(item));
}
Db.Ado.CommandTimeOut = 30; // 设置30秒超时
//功能写法可以将插入和更新拆开,然后调用插入和更新独有特性
var x = Db.Storageable(item).ToStorage();
var rst = await x.AsInsertable.ExecuteCommandAsync();//不存在插入
var rst2 = await x.AsUpdateable.ExecuteCommandAsync();//存在更新
return rst + rst2;
}
public virtual async Task<int> RemoveAsync(Expression<Func<TEntity, bool>> filter)
{
if (filter == null) return -1;
if (typeof(TEntity).IsAssignableFrom(typeof(ILogicDelete)))
{
var rst = this.Db.Updateable<TEntity>()
.SetColumns(t => ((ILogicDelete)t).IsDeleted == true)
.Where(filter);
return await rst.ExecuteCommandAsync();
}
else
return await Db.Deleteable<TEntity>().Where(filter).ExecuteCommandAsync();
}
public virtual async Task<int> RemoveAsync(params string[] keys)
{
if (keys == null)
{
throw new ArgumentNullException(nameof(keys));
}
return await this.RemoveAsync(t => keys.Contains(t.Id));
}
public async Task<int> UpdateAsync(TEntity item)
{
return await Db.Updateable<TEntity>(item).ExecuteCommandAsync();
}
public async Task<int> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> where)
{
return await Db.Updateable<TEntity>()
.SetColumns(columns)//类只能在表达示里面不能提取
.Where(where)
.ExecuteCommandAsync();
}
public async Task<int> UpdatesAsync(List<TEntity> entities, Expression<Func<TEntity, object>> columns)
{
return await Db.Updateable(entities)
.UpdateColumns(columns)
.ExecuteCommandAsync();
}
#endregion
#region
public async virtual Task<bool> ExistsAsync(string key)
{
if (EqualityComparer<string>.Default.Equals(key, default(string)))
{
return false;
}
return await this.Db.Queryable<TEntity>().AnyAsync(t => t.Id != null && t.Id.Equals(key));
}
public async virtual Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> filter)
{
if (filter == null)
{
return false;
}
//// 应用过滤器
//foreach (var ft in this.Options.QueryFilters)
//{
// var exp = ft.Value.GetFilter<TEntity>();
// if (exp != null)
// {
// filter = filter.AndAlso(exp);
// }
//}
return await this.Db.Queryable<TEntity>().AnyAsync(filter);
}
public async Task<IEnumerable<TEntity>> GetAllAsync(IEnumerable<SelectSort<TEntity>> sorts = null)
{
try
{
// 获取可查询对象
var query = ContextManage.Queryable<TEntity>();
// 如果有排序条件,则应用排序
if (sorts != null && sorts.Any())
{
query = query.OrderBy(sorts);
}
Type type = typeof(TEntity);
// 如果实现了ILogicDelete接口且filter不包含IsDeleted条件则添加IsDeleted=false条件
if (typeof(ILogicDelete).IsAssignableFrom(type))
{
query = query.Where(t => ((ILogicDelete)t).IsDeleted == false);
}
// 返回查询结果
return await query.ToListAsync();
}
catch (Exception ex)
{
throw new Exception("无法从数据库中检索数据.", ex);
}
}
public async virtual Task<TEntity> FindByAsync(string key)
{
if (EqualityComparer<string>.Default.Equals(key, default(string)))
{
return default(TEntity);
}
return await this.Db.Queryable<TEntity>().Where(t => t.Id != null && t.Id.Equals(key)).FirstAsync();
}
public async virtual Task<TEntity> GetFirstOrDefaultAsync(Expression<Func<TEntity, bool>> filter)
{
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
return await this.Db.Queryable<TEntity>().Where(filter).FirstAsync();
}
public async virtual Task<IEnumerable<TEntity>> GetListByExpAsync(Expression<Func<TEntity, bool>> filter, IEnumerable<SelectSort<TEntity>> sorts = null)
{
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
Type type = typeof(TEntity);
// 如果实现了ILogicDelete接口且filter不包含IsDeleted条件则添加IsDeleted=false条件
if (typeof(ILogicDelete).IsAssignableFrom(type))
{
if (!filter.ToString().Contains("IsDeleted"))
{
// 动态构建 t.IsDeleted == false 条件
filter = filter.AndAlso(t => ((ILogicDelete)t).IsDeleted == false);
}
}
var setAll = this.Db.Queryable<TEntity>().Where(filter);
if (sorts != null)
setAll = setAll.OrderBy(sorts);
return await setAll.ToListAsync();
}
/// <summary>
/// EF 版本EF实现指定字段查询比较困难所以先查出所有字段
/// </summary>
/// <param name="columnNames"></param>
/// <param name="filter"></param>
/// <param name="sorts"></param>
/// <returns></returns>
public async virtual Task<IEnumerable<TEntity>> GetListWithColumnsAsync(IEnumerable<string> columnNames, Expression<Func<TEntity, bool>> filter, IEnumerable<SelectSort<TEntity>> sorts = null)
{
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
Type type = typeof(TEntity);
// 如果实现了ILogicDelete接口且filter不包含IsDeleted条件则添加IsDeleted=false条件
if (typeof(ILogicDelete).IsAssignableFrom(type))
{
if (!filter.ToString().Contains("IsDeleted"))
{
// 动态构建 t.IsDeleted == false 条件
filter = filter.AndAlso(t => ((ILogicDelete)t).IsDeleted == false);
}
}
var rst = await GetListByExpAsync(filter, sorts);
return rst;
}
public async virtual Task<IListResult<TEntity>> GetPagedAsync(int pageIndex, int pageSize, Expression<Func<TEntity, bool>> filter, IEnumerable<SelectSort<TEntity>> sorts)
{
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
RefAsync<int> total = 0;
Type type = typeof(TEntity);
// 如果实现了ILogicDelete接口且filter不包含IsDeleted条件则添加IsDeleted=false条件
if (typeof(ILogicDelete).IsAssignableFrom(type))
{
if (!filter.ToString().Contains("IsDeleted"))
{
// 动态构建 t.IsDeleted == false 条件
filter = filter.AndAlso(t => ((ILogicDelete)t).IsDeleted == false);
}
}
var resultSet = this.Db.Queryable<TEntity>().Where(filter);
if (sorts != null)
resultSet = resultSet.OrderBy(sorts);
var pageData = await resultSet.ToPageListAsync(pageIndex, pageSize, total);
return base.ListData(pageData, total);
}
public async virtual Task<IListResult<TEntity>> GetPagedAsync(DataSourceLoadOptions loadOptions)
{
var query = this.Db.Queryable<TEntity>();
var datas=await query.LoadAsync(loadOptions);
return datas;
}
#endregion
#region
public async Task<int> CountAsync(Expression<Func<TEntity, bool>> filter)
{
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
return await this.Db.Queryable<TEntity>().CountAsync(filter);
}
public async Task<TValue> MaxAsync<TValue>(Expression<Func<TEntity, TValue>> selector, Expression<Func<TEntity, bool>> filter = null)
{
if (selector is null)
{
throw new ArgumentNullException(nameof(selector));
}
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
return await this.Db.Queryable<TEntity>().Where(filter).MaxAsync(selector);
}
public async Task<TValue> MinAsync<TValue>(Expression<Func<TEntity, TValue>> selector, Expression<Func<TEntity, bool>> filter = null)
{
if (selector is null)
{
throw new ArgumentNullException(nameof(selector));
}
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
return await this.Db.Queryable<TEntity>().Where(filter).MinAsync(selector);
}
public async Task<decimal> SumAsync(Expression<Func<TEntity, decimal>> selector, Expression<Func<TEntity, bool>> filter = null)
{
if (selector is null)
{
throw new ArgumentNullException(nameof(selector));
}
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
return await this.Db.Queryable<TEntity>().Where(filter).SumAsync(selector);
}
public async Task<decimal> AVGAsync(Expression<Func<TEntity, decimal>> selector, Expression<Func<TEntity, bool>> filter = null)
{
if (selector is null)
{
throw new ArgumentNullException(nameof(selector));
}
if (filter is null)
{
throw new ArgumentNullException(nameof(filter));
}
return await this.Db.Queryable<TEntity>().Where(filter).AvgAsync(selector);
}
public Task<int> SaveChangesAsync()
{
throw new NotImplementedException("sqlsugar 不支持");
}
#endregion
}
}