BaseRepository.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. using System.Linq.Expressions;
  2. using Hotline.Repository.SqlSugar.DataPermissions;
  3. using Hotline.Repository.SqlSugar.Extensions;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Novacode;
  6. using SqlSugar;
  7. using XF.Domain.Entities;
  8. using XF.Domain.Repository;
  9. using XF.Domain.Repository.Events;
  10. namespace Hotline.Repository.SqlSugar
  11. {
  12. public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity<string>, IHasCreationTime, IDataPermission, new()
  13. {
  14. private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder;
  15. protected ISugarUnitOfWork<HotlineDbContext> Uow { get; }
  16. protected ISqlSugarClient Db { get; }
  17. private readonly IServiceProvider _serviceProvider;
  18. public BaseRepository(ISugarUnitOfWork<HotlineDbContext> uow, IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider)
  19. {
  20. Uow = uow;
  21. Db = uow.Db;
  22. _dataPermissionFilterBuilder = dataPermissionFilterBuilder;
  23. _serviceProvider = serviceProvider;
  24. }
  25. public async Task<string> AddAsync(TEntity entity, CancellationToken cancellationToken = default)
  26. {
  27. entity.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager);
  28. var excEntity = await Db.Insertable(entity).ExecuteReturnEntityAsync();
  29. return excEntity.Id;
  30. }
  31. public async Task<string> AddAsync(TEntity entity,bool isCreator , CancellationToken cancellationToken = default)
  32. {
  33. if (isCreator)
  34. {
  35. entity.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager);
  36. }
  37. var excEntity = await Db.Insertable(entity).ExecuteReturnEntityAsync();
  38. return excEntity.Id;
  39. }
  40. /// <summary>
  41. /// 批量插入(应用场景:小数据量,超出1万条建议另行实现)
  42. /// </summary>
  43. /// <param name="entities"></param>
  44. /// <param name="cancellationToken"></param>
  45. /// <returns></returns>
  46. public async Task AddRangeAsync(List<TEntity> entities, CancellationToken cancellationToken = default)
  47. {
  48. entities.ForEach(d => d.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager));
  49. await Db.Insertable(entities).ExecuteCommandAsync(cancellationToken);
  50. }
  51. public async Task RemoveAsync(TEntity entity, bool? soft = false, CancellationToken cancellationToken = default)
  52. {
  53. if (soft.HasValue && soft.Value)
  54. {
  55. await Db.Deleteable(entity).IsLogic().ExecuteCommandAsync("IsDeleted", true, "DeletionTime");
  56. }
  57. else
  58. {
  59. await Db.Deleteable(entity).ExecuteCommandAsync(cancellationToken);
  60. }
  61. }
  62. public async Task RemoveAsync(string id, bool? soft = false, CancellationToken cancellationToken = default)
  63. {
  64. if (soft.HasValue && soft.Value)
  65. {
  66. await Db.Deleteable<TEntity>().In(id).IsLogic().ExecuteCommandAsync("IsDeleted", true, "DeletionTime");
  67. }
  68. else
  69. {
  70. await Db.Deleteable<TEntity>().In(id).ExecuteCommandAsync(cancellationToken);
  71. }
  72. }
  73. public async Task RemoveAsync(Expression<Func<TEntity, bool>> predicate, bool? soft, CancellationToken cancellationToken = default)
  74. {
  75. if (soft.HasValue && soft.Value)
  76. {
  77. await Db.Deleteable<TEntity>().Where(predicate).IsLogic().ExecuteCommandAsync("IsDeleted", true, "DeletionTime");
  78. }
  79. else
  80. {
  81. await Db.Deleteable<TEntity>().Where(predicate).ExecuteCommandAsync(cancellationToken);
  82. }
  83. }
  84. public async Task RemoveRangeAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default)
  85. {
  86. await Db.Deleteable<TEntity>(entities).ExecuteCommandAsync(cancellationToken);
  87. }
  88. public async Task RemoveRangeAsync(IEnumerable<TEntity> entities, bool? soft, CancellationToken cancellationToken = default)
  89. {
  90. if (soft.HasValue && soft.Value)
  91. {
  92. await Db.Deleteable<TEntity>(entities).IsLogic().ExecuteCommandAsync("IsDeleted", true, "DeletionTime");
  93. }
  94. else
  95. {
  96. await Db.Deleteable<TEntity>(entities).ExecuteCommandAsync(cancellationToken);
  97. }
  98. }
  99. public async Task UpdateAsync(TEntity entity, CancellationToken cancellationToken = default)
  100. {
  101. await Db.Updateable(entity)
  102. .IgnoreColumns(ignoreAllNullColumns: true)
  103. .IgnoreColumns(d => d.CreationTime)
  104. .ExecuteCommandAsync(cancellationToken);
  105. }
  106. public async Task UpdateNullAsync(TEntity entity, CancellationToken cancellationToken = default)
  107. {
  108. await Db.Updateable(entity)
  109. .IgnoreColumns(d => d.CreationTime)
  110. .ExecuteCommandAsync(cancellationToken);
  111. }
  112. public async Task UpdateRangeAsync(List<TEntity> entities, CancellationToken cancellationToken = default)
  113. {
  114. await Db.Updateable(entities)
  115. .IgnoreColumns(d => d.CreationTime)
  116. .ExecuteCommandAsync(cancellationToken);
  117. }
  118. public async Task<TEntity?> GetAsync(string id, CancellationToken cancellationToken = default)
  119. {
  120. return await Db.Queryable<TEntity>().FirstAsync(d => d.Id == id, cancellationToken);
  121. }
  122. public TEntity Get(string id)
  123. {
  124. return Db.Queryable<TEntity>().First(d => d.Id == id);
  125. }
  126. public TEntity Get(Expression<Func<TEntity, bool>> predicate)
  127. {
  128. return Db.Queryable<TEntity>().First(predicate);
  129. }
  130. public async Task<TEntity?> GetAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
  131. {
  132. return await Db.Queryable<TEntity>().FirstAsync(predicate, cancellationToken);
  133. }
  134. public async Task<TEntity?> GetAsync(Expression<Func<TEntity, bool>> predicate, bool isDesc, Expression<Func<TEntity, object>> orderBy, CancellationToken cancellationToken = default)
  135. {
  136. if (isDesc)
  137. return await Db.Queryable<TEntity>().OrderBy(orderBy, OrderByType.Desc).FirstAsync(predicate, cancellationToken);
  138. else
  139. return await Db.Queryable<TEntity>().OrderBy(orderBy, OrderByType.Asc).FirstAsync(predicate, cancellationToken);
  140. }
  141. public async Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>>? predicate = null, params (bool isWhere, Expression<Func<TEntity, bool>> expression)[] whereIfs)
  142. {
  143. var query = Db.Queryable<TEntity>().Where(predicate ??= d => true);
  144. if (whereIfs.Any())
  145. {
  146. foreach (var whereIf in whereIfs)
  147. {
  148. query = query.WhereIF(whereIf.isWhere, whereIf.expression);
  149. }
  150. }
  151. return await query.ToListAsync();
  152. }
  153. public Task<bool> AnyAsync(CancellationToken cancellationToken = default) => Db.Queryable<TEntity>().AnyAsync();
  154. public Task<bool> AnyAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default) =>
  155. Db.Queryable<TEntity>().AnyAsync(predicate, cancellationToken);
  156. public Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default) =>
  157. Db.Queryable<TEntity>().CountAsync(predicate, cancellationToken);
  158. public ISugarQueryable<TEntity> Queryable(bool permissionVerify = false, bool includeDeleted = false)
  159. {
  160. if (includeDeleted)
  161. Db.QueryFilter.Clear();
  162. var query = Db.Queryable<TEntity>();
  163. if (permissionVerify)
  164. query = query.DataPermissionFiltering(_dataPermissionFilterBuilder);
  165. return query;
  166. }
  167. public IUpdateable<TEntity> Updateable() => Db.Updateable<TEntity>();
  168. public IUpdateable<TEntity> Updateable(TEntity entity) => Db.Updateable(entity);
  169. public IUpdateable<TEntity> Updateable(List<TEntity> entities) => Db.Updateable(entities);
  170. public IDeleteable<TEntity> Removeable() => Db.Deleteable<TEntity>();
  171. public UpdateNavTaskInit<TEntity, TEntity> UpdateNav(TEntity entity) => Db.UpdateNav(entity);
  172. public UpdateNavTaskInit<TEntity, TEntity> UpdateNav(TEntity entity, UpdateNavRootOptions options) => Db.UpdateNav(entity, options);
  173. public UpdateNavTaskInit<TEntity, TEntity> UpdateNav(List<TEntity> entities) => Db.UpdateNav(entities);
  174. public UpdateNavTaskInit<TEntity, TEntity> UpdateNav(List<TEntity> entities, UpdateNavRootOptions options) => Db.UpdateNav(entities, options);
  175. public InsertNavTaskInit<TEntity, TEntity> AddNav(TEntity entity)
  176. {
  177. var dataPermissionManager = _dataPermissionFilterBuilder.DataPermissionManager;
  178. entity.InitDatePermission(dataPermissionManager);
  179. return Db.InsertNav(entity);
  180. }
  181. public InsertNavTaskInit<TEntity, TEntity> AddNav(TEntity entity, InsertNavRootOptions options)
  182. {
  183. entity.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager);
  184. return Db.InsertNav(entity, options);
  185. }
  186. public InsertNavTaskInit<TEntity, TEntity> AddNav(List<TEntity> entities)
  187. {
  188. entities.ForEach(d => d.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager));
  189. return Db.InsertNav(entities);
  190. }
  191. public InsertNavTaskInit<TEntity, TEntity> AddNav(List<TEntity> entities, InsertNavRootOptions options)
  192. {
  193. entities.ForEach(d => d.InitDatePermission(_dataPermissionFilterBuilder.DataPermissionManager));
  194. return Db.InsertNav(entities, options);
  195. }
  196. public DeleteNavTaskInit<TEntity, TEntity> RemoveNav(TEntity entity) => Db.DeleteNav(entity);
  197. public DeleteNavTaskInit<TEntity, TEntity> RemoveNav(List<TEntity> entities) => Db.DeleteNav(entities);
  198. public DeleteNavTaskInit<TEntity, TEntity> RemoveNav(Expression<Func<TEntity, bool>> predicate) => Db.DeleteNav(predicate);
  199. public ISugarQueryable<TEntity> UnionAll(params ISugarQueryable<TEntity>[] queryables) => Db.UnionAll(queryables);
  200. /// <summary>
  201. /// 基础分页
  202. /// </summary>
  203. /// <param name="predicate"></param>
  204. /// <param name="orderByCreator"></param>
  205. /// <param name="pageIndex"></param>
  206. /// <param name="pageSize"></param>
  207. /// <param name="permissionVerify"></param>
  208. /// <returns></returns>
  209. public async Task<(int Total, List<TEntity> Items)> QueryPagedAsync(
  210. Expression<Func<TEntity, bool>> predicate,
  211. Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> orderByCreator,
  212. int pageIndex,
  213. int pageSize,
  214. bool permissionVerify = false,
  215. params (bool isWhere, Expression<Func<TEntity, bool>> expression)[] whereIfs)
  216. {
  217. RefAsync<int> total = 0;
  218. var query = Db.Queryable<TEntity>().Where(predicate);
  219. if (permissionVerify)
  220. query = query.DataPermissionFiltering(_dataPermissionFilterBuilder);
  221. if (whereIfs.Any())
  222. {
  223. foreach (var whereIf in whereIfs)
  224. {
  225. query = query.WhereIF(whereIf.isWhere, whereIf.expression);
  226. }
  227. }
  228. var items = await orderByCreator(query).ToPageListAsync(pageIndex, pageSize, total);
  229. return (total.Value, items);
  230. }
  231. public async Task<(int Total, List<TEntity> Items)> QueryPagedAsync(
  232. Expression<Func<TEntity, bool>> predicate,
  233. int pageIndex,
  234. int pageSize,
  235. Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>>? includes = null,
  236. Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>>? orderByCreator = null,
  237. bool permissionVerify = false,
  238. params (bool isWhere, Expression<Func<TEntity, bool>> expression)[] whereIfs)
  239. {
  240. RefAsync<int> total = 0;
  241. var query = Db.Queryable<TEntity>().Where(predicate);
  242. if (permissionVerify)
  243. query = query.DataPermissionFiltering(_dataPermissionFilterBuilder);
  244. if (includes is not null)
  245. query = includes(query);
  246. if (whereIfs.Any())
  247. {
  248. foreach (var whereIf in whereIfs)
  249. {
  250. query = query.WhereIF(whereIf.isWhere, whereIf.expression);
  251. }
  252. }
  253. if (orderByCreator is not null)
  254. query = orderByCreator(query);
  255. var items = await query.ToPageListAsync(pageIndex, pageSize, total);
  256. return (total.Value, items);
  257. }
  258. public async Task<List<TEntity>> QueryExtAsync(
  259. Expression<Func<TEntity, bool>> predicate,
  260. Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>>? includes = null,
  261. Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>>? orderByCreator = null,
  262. bool permissionVerify = false,
  263. params (bool isWhere, Expression<Func<TEntity, bool>> expression)[] whereIfs)
  264. {
  265. var query = Db.Queryable<TEntity>().Where(predicate);
  266. if (permissionVerify)
  267. query = query.DataPermissionFiltering(_dataPermissionFilterBuilder);
  268. if (includes is not null)
  269. query = includes(query);
  270. if (whereIfs.Any())
  271. {
  272. foreach (var whereIf in whereIfs)
  273. {
  274. query = query.WhereIF(whereIf.isWhere, whereIf.expression);
  275. }
  276. }
  277. if (orderByCreator is not null)
  278. query = orderByCreator(query);
  279. return await query.ToListAsync();
  280. }
  281. public async Task<List<TEntity>> QueryExtAsync(
  282. Expression<Func<TEntity, bool>> predicate,
  283. Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes,
  284. bool permissionVerify = false)
  285. {
  286. var query = Db.Queryable<TEntity>().Where(predicate);
  287. if (permissionVerify)
  288. query = query.DataPermissionFiltering(_dataPermissionFilterBuilder);
  289. query = includes(query);
  290. return await query.ToListAsync();
  291. }
  292. public async Task<TEntity> GetExtAsync(
  293. Expression<Func<TEntity, bool>> predicate,
  294. Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes,
  295. bool permissionVerify = false)
  296. {
  297. var query = Db.Queryable<TEntity>();
  298. if (permissionVerify)
  299. query = query.DataPermissionFiltering(_dataPermissionFilterBuilder);
  300. query = includes(query);
  301. return await query.FirstAsync(predicate);
  302. }
  303. public async Task<TEntity> GetExtAsync(string id, Func<ISugarQueryable<TEntity>, ISugarQueryable<TEntity>> includes, bool permissionVerify = false)
  304. {
  305. var query = Db.Queryable<TEntity>();
  306. if (permissionVerify)
  307. query = query.DataPermissionFiltering(_dataPermissionFilterBuilder);
  308. query = includes(query);
  309. return await query.FirstAsync(d => d.Id == id);
  310. }
  311. public async Task UpdateAsync(TEntity entity, bool ignoreNullColumns = true, CancellationToken cancellationToken = default)
  312. {
  313. try
  314. {
  315. _serviceProvider.GetService<DatabaseEventDispatcher>()?.Dispatch(entity, DataFilterType.UpdateByObject, true);
  316. }
  317. catch (Exception e)
  318. {
  319. var msg = e.Message;
  320. }
  321. await Db.Updateable(entity)
  322. .IgnoreColumns(ignoreAllNullColumns: ignoreNullColumns)
  323. .IgnoreColumns(d => d.CreationTime)
  324. .ExecuteCommandAsync(cancellationToken);
  325. }
  326. }
  327. }