using System.Linq.Expressions; using Hotline.Repository.SqlSugar.DataPermissions; using Hotline.Repository.SqlSugar.Extensions; using Microsoft.Extensions.DependencyInjection; using Novacode; using SqlSugar; using XF.Domain.Entities; using XF.Domain.Repository; using XF.Domain.Repository.Events; namespace Hotline.Repository.SqlSugar { public class BaseRepository : IRepository where TEntity : class, IEntity, IHasCreationTime, IDataPermission, new() { private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder; protected ISugarUnitOfWork Uow { get; } protected ISqlSugarClient Db { get; } private readonly IServiceProvider _serviceProvider; public BaseRepository(ISugarUnitOfWork uow, IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider) { Uow = uow; Db = uow.Db; _dataPermissionFilterBuilder = dataPermissionFilterBuilder; _serviceProvider = serviceProvider; } public async Task AddAsync(TEntity entity, CancellationToken cancellationToken = default) { entity.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager); var excEntity = await Db.Insertable(entity).ExecuteReturnEntityAsync(); return excEntity.Id; } public async Task AddAsync(TEntity entity,bool isCreator , CancellationToken cancellationToken = default) { if (isCreator) { entity.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager); } var excEntity = await Db.Insertable(entity).ExecuteReturnEntityAsync(); return excEntity.Id; } /// /// 批量插入(应用场景:小数据量,超出1万条建议另行实现) /// /// /// /// public async Task AddRangeAsync(List entities, CancellationToken cancellationToken = default) { entities.ForEach(d => d.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager)); await Db.Insertable(entities).ExecuteCommandAsync(cancellationToken); } public async Task RemoveAsync(TEntity entity, bool? soft = false, CancellationToken cancellationToken = default) { if (soft.HasValue && soft.Value) { await Db.Deleteable(entity).IsLogic().ExecuteCommandAsync("IsDeleted", true, "DeletionTime"); } else { await Db.Deleteable(entity).ExecuteCommandAsync(cancellationToken); } } public async Task RemoveAsync(string id, bool? soft = false, CancellationToken cancellationToken = default) { if (soft.HasValue && soft.Value) { await Db.Deleteable().In(id).IsLogic().ExecuteCommandAsync("IsDeleted", true, "DeletionTime"); } else { await Db.Deleteable().In(id).ExecuteCommandAsync(cancellationToken); } } public async Task RemoveAsync(Expression> predicate, bool? soft, CancellationToken cancellationToken = default) { if (soft.HasValue && soft.Value) { await Db.Deleteable().Where(predicate).IsLogic().ExecuteCommandAsync("IsDeleted", true, "DeletionTime"); } else { await Db.Deleteable().Where(predicate).ExecuteCommandAsync(cancellationToken); } } public async Task RemoveRangeAsync(IEnumerable entities, CancellationToken cancellationToken = default) { await Db.Deleteable(entities).ExecuteCommandAsync(cancellationToken); } public async Task RemoveRangeAsync(IEnumerable entities, bool? soft, CancellationToken cancellationToken = default) { if (soft.HasValue && soft.Value) { await Db.Deleteable(entities).IsLogic().ExecuteCommandAsync("IsDeleted", true, "DeletionTime"); } else { await Db.Deleteable(entities).ExecuteCommandAsync(cancellationToken); } } public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default) { await Db.Updateable(entity) .IgnoreColumns(ignoreAllNullColumns: true) .IgnoreColumns(d => d.CreationTime) .ExecuteCommandAsync(cancellationToken); } public async Task UpdateNullAsync(TEntity entity, CancellationToken cancellationToken = default) { await Db.Updateable(entity) .IgnoreColumns(d => d.CreationTime) .ExecuteCommandAsync(cancellationToken); } public async Task UpdateRangeAsync(List entities, CancellationToken cancellationToken = default) { await Db.Updateable(entities) .IgnoreColumns(d => d.CreationTime) .ExecuteCommandAsync(cancellationToken); } public async Task GetAsync(string id, CancellationToken cancellationToken = default) { return await Db.Queryable().FirstAsync(d => d.Id == id, cancellationToken); } public TEntity Get(string id) { return Db.Queryable().First(d => d.Id == id); } public TEntity Get(Expression> predicate) { return Db.Queryable().First(predicate); } public async Task GetAsync(Expression> predicate, CancellationToken cancellationToken = default) { return await Db.Queryable().FirstAsync(predicate, cancellationToken); } public async Task GetAsync(Expression> predicate, bool isDesc, Expression> orderBy, CancellationToken cancellationToken = default) { if (isDesc) return await Db.Queryable().OrderBy(orderBy, OrderByType.Desc).FirstAsync(predicate, cancellationToken); else return await Db.Queryable().OrderBy(orderBy, OrderByType.Asc).FirstAsync(predicate, cancellationToken); } public async Task> QueryAsync(Expression>? predicate = null, params (bool isWhere, Expression> expression)[] whereIfs) { var query = Db.Queryable().Where(predicate ??= d => true); if (whereIfs.Any()) { foreach (var whereIf in whereIfs) { query = query.WhereIF(whereIf.isWhere, whereIf.expression); } } return await query.ToListAsync(); } public Task AnyAsync(CancellationToken cancellationToken = default) => Db.Queryable().AnyAsync(); public Task AnyAsync(Expression> predicate, CancellationToken cancellationToken = default) => Db.Queryable().AnyAsync(predicate, cancellationToken); public Task CountAsync(Expression> predicate, CancellationToken cancellationToken = default) => Db.Queryable().CountAsync(predicate, cancellationToken); public ISugarQueryable Queryable(bool permissionVerify = false, bool includeDeleted = false) { if (includeDeleted) Db.QueryFilter.Clear(); var query = Db.Queryable(); if (permissionVerify) query = query.DataPermissionFiltering(_dataPermissionFilterBuilder); return query; } public IUpdateable Updateable() => Db.Updateable(); public IUpdateable Updateable(TEntity entity) => Db.Updateable(entity); public IUpdateable Updateable(List entities) => Db.Updateable(entities); public IDeleteable Removeable() => Db.Deleteable(); public UpdateNavTaskInit UpdateNav(TEntity entity) => Db.UpdateNav(entity); public UpdateNavTaskInit UpdateNav(TEntity entity, UpdateNavRootOptions options) => Db.UpdateNav(entity, options); public UpdateNavTaskInit UpdateNav(List entities) => Db.UpdateNav(entities); public UpdateNavTaskInit UpdateNav(List entities, UpdateNavRootOptions options) => Db.UpdateNav(entities, options); public InsertNavTaskInit AddNav(TEntity entity) { var dataPermissionManager = _dataPermissionFilterBuilder.DataPermissionManager; entity.InitDatePermission(dataPermissionManager); return Db.InsertNav(entity); } public InsertNavTaskInit AddNav(TEntity entity, InsertNavRootOptions options) { entity.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager); return Db.InsertNav(entity, options); } public InsertNavTaskInit AddNav(List entities) { entities.ForEach(d => d.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager)); return Db.InsertNav(entities); } public InsertNavTaskInit AddNav(List entities, InsertNavRootOptions options) { entities.ForEach(d => d.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager)); return Db.InsertNav(entities, options); } public DeleteNavTaskInit RemoveNav(TEntity entity) => Db.DeleteNav(entity); public DeleteNavTaskInit RemoveNav(List entities) => Db.DeleteNav(entities); public DeleteNavTaskInit RemoveNav(Expression> predicate) => Db.DeleteNav(predicate); public ISugarQueryable UnionAll(params ISugarQueryable[] queryables) => Db.UnionAll(queryables); /// /// 基础分页 /// /// /// /// /// /// /// public async Task<(int Total, List Items)> QueryPagedAsync( Expression> predicate, Func, ISugarQueryable> orderByCreator, int pageIndex, int pageSize, bool permissionVerify = false, params (bool isWhere, Expression> expression)[] whereIfs) { RefAsync total = 0; var query = Db.Queryable().Where(predicate); if (permissionVerify) query = query.DataPermissionFiltering(_dataPermissionFilterBuilder); if (whereIfs.Any()) { foreach (var whereIf in whereIfs) { query = query.WhereIF(whereIf.isWhere, whereIf.expression); } } var items = await orderByCreator(query).ToPageListAsync(pageIndex, pageSize, total); return (total.Value, items); } public async Task<(int Total, List Items)> QueryPagedAsync( Expression> predicate, int pageIndex, int pageSize, Func, ISugarQueryable>? includes = null, Func, ISugarQueryable>? orderByCreator = null, bool permissionVerify = false, params (bool isWhere, Expression> expression)[] whereIfs) { RefAsync total = 0; var query = Db.Queryable().Where(predicate); if (permissionVerify) query = query.DataPermissionFiltering(_dataPermissionFilterBuilder); if (includes is not null) query = includes(query); if (whereIfs.Any()) { foreach (var whereIf in whereIfs) { query = query.WhereIF(whereIf.isWhere, whereIf.expression); } } if (orderByCreator is not null) query = orderByCreator(query); var items = await query.ToPageListAsync(pageIndex, pageSize, total); return (total.Value, items); } public async Task> QueryExtAsync( Expression> predicate, Func, ISugarQueryable>? includes = null, Func, ISugarQueryable>? orderByCreator = null, bool permissionVerify = false, params (bool isWhere, Expression> expression)[] whereIfs) { var query = Db.Queryable().Where(predicate); if (permissionVerify) query = query.DataPermissionFiltering(_dataPermissionFilterBuilder); if (includes is not null) query = includes(query); if (whereIfs.Any()) { foreach (var whereIf in whereIfs) { query = query.WhereIF(whereIf.isWhere, whereIf.expression); } } if (orderByCreator is not null) query = orderByCreator(query); return await query.ToListAsync(); } public async Task> QueryExtAsync( Expression> predicate, Func, ISugarQueryable> includes, bool permissionVerify = false) { var query = Db.Queryable().Where(predicate); if (permissionVerify) query = query.DataPermissionFiltering(_dataPermissionFilterBuilder); query = includes(query); return await query.ToListAsync(); } public async Task GetExtAsync( Expression> predicate, Func, ISugarQueryable> includes, bool permissionVerify = false) { var query = Db.Queryable(); if (permissionVerify) query = query.DataPermissionFiltering(_dataPermissionFilterBuilder); query = includes(query); return await query.FirstAsync(predicate); } public async Task GetExtAsync(string id, Func, ISugarQueryable> includes, bool permissionVerify = false) { var query = Db.Queryable(); if (permissionVerify) query = query.DataPermissionFiltering(_dataPermissionFilterBuilder); query = includes(query); return await query.FirstAsync(d => d.Id == id); } public async Task UpdateAsync(TEntity entity, bool ignoreNullColumns = true, CancellationToken cancellationToken = default) { try { _serviceProvider.GetService()?.Dispatch(entity, DataFilterType.UpdateByObject, true); } catch (Exception e) { var msg = e.Message; } await Db.Updateable(entity) .IgnoreColumns(ignoreAllNullColumns: ignoreNullColumns) .IgnoreColumns(d => d.CreationTime) .ExecuteCommandAsync(cancellationToken); } } }