TemplatePro/BZPT.SqlSugarRepository/RepositoryBase.cs

411 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***********************************************************
**项目名称:
**功能描述: 仓储 的摘要说明
**作 者: 易栋梁
**版 本 号: 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 KubeClient.Models;
using SqlSugar;
using Consul.Filtering;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using MathNet.Numerics.Distributions;
using ServiceStack;
using NPOI.SS.Formula.Functions;
using Mysqlx.Expr;
using System.Text;
using NPlatform.Infrastructure.IdGenerators;
using static ServiceStack.Diagnostics;
using NPlatform.Filters;
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 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= ObjectIdGenerator.Instance.GetId().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));
}
//功能写法可以将插入和更新拆开,然后调用插入和更新独有特性
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();
}
#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 Task<IEnumerable<TEntity>> GetAllAsync(IEnumerable<SelectSort<TEntity>> sorts = null)
{
throw new Exception("未实现");
}
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));
}
var setAll = this.Db.Queryable<TEntity>().Where(filter).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));
}
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;
var resultSet = await this.Db.Queryable<TEntity>().Where(filter).OrderBy(sorts).ToPageListAsync(pageIndex, pageSize, total);
return base.ListData(resultSet, total);
}
#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
}
}