AbpRepositoryBase.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Threading.Tasks;
  6. using Abp.Dependency;
  7. using Abp.Domain.Entities;
  8. using Abp.Domain.Uow;
  9. using Abp.MultiTenancy;
  10. using Abp.Reflection.Extensions;
  11. namespace Abp.Domain.Repositories
  12. {
  13. /// <summary>
  14. /// Base class to implement <see cref="IRepository{TEntity,TPrimaryKey}"/>.
  15. /// It implements some methods in most simple way.
  16. /// </summary>
  17. /// <typeparam name="TEntity">Type of the Entity for this repository</typeparam>
  18. /// <typeparam name="TPrimaryKey">Primary key of the entity</typeparam>
  19. public abstract class AbpRepositoryBase<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey>, IUnitOfWorkManagerAccessor
  20. where TEntity : class, IEntity<TPrimaryKey>
  21. {
  22. /// <summary>
  23. /// The multi tenancy side
  24. /// </summary>
  25. public static MultiTenancySides? MultiTenancySide { get; private set; }
  26. public IUnitOfWorkManager UnitOfWorkManager { get; set; }
  27. public IIocResolver IocResolver { get; set; }
  28. static AbpRepositoryBase()
  29. {
  30. var attr = typeof (TEntity).GetSingleAttributeOfTypeOrBaseTypesOrNull<MultiTenancySideAttribute>();
  31. if (attr != null)
  32. {
  33. MultiTenancySide = attr.Side;
  34. }
  35. }
  36. public abstract IQueryable<TEntity> GetAll();
  37. public virtual IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] propertySelectors)
  38. {
  39. return GetAll();
  40. }
  41. public virtual List<TEntity> GetAllList()
  42. {
  43. return GetAll().ToList();
  44. }
  45. public virtual Task<List<TEntity>> GetAllListAsync()
  46. {
  47. return Task.FromResult(GetAllList());
  48. }
  49. public virtual List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate)
  50. {
  51. return GetAll().Where(predicate).ToList();
  52. }
  53. public virtual Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate)
  54. {
  55. return Task.FromResult(GetAllList(predicate));
  56. }
  57. public virtual T Query<T>(Func<IQueryable<TEntity>, T> queryMethod)
  58. {
  59. return queryMethod(GetAll());
  60. }
  61. public virtual TEntity Get(TPrimaryKey id)
  62. {
  63. var entity = FirstOrDefault(id);
  64. if (entity == null)
  65. {
  66. throw new EntityNotFoundException(typeof(TEntity), id);
  67. }
  68. return entity;
  69. }
  70. public virtual async Task<TEntity> GetAsync(TPrimaryKey id)
  71. {
  72. var entity = await FirstOrDefaultAsync(id);
  73. if (entity == null)
  74. {
  75. throw new EntityNotFoundException(typeof(TEntity), id);
  76. }
  77. return entity;
  78. }
  79. public virtual TEntity Single(Expression<Func<TEntity, bool>> predicate)
  80. {
  81. return GetAll().Single(predicate);
  82. }
  83. public virtual Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate)
  84. {
  85. return Task.FromResult(Single(predicate));
  86. }
  87. public virtual TEntity FirstOrDefault(TPrimaryKey id)
  88. {
  89. return GetAll().FirstOrDefault(CreateEqualityExpressionForId(id));
  90. }
  91. public virtual Task<TEntity> FirstOrDefaultAsync(TPrimaryKey id)
  92. {
  93. return Task.FromResult(FirstOrDefault(id));
  94. }
  95. public virtual TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate)
  96. {
  97. return GetAll().FirstOrDefault(predicate);
  98. }
  99. public virtual Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate)
  100. {
  101. return Task.FromResult(FirstOrDefault(predicate));
  102. }
  103. public virtual TEntity Load(TPrimaryKey id)
  104. {
  105. return Get(id);
  106. }
  107. public abstract TEntity Insert(TEntity entity);
  108. public virtual Task<TEntity> InsertAsync(TEntity entity)
  109. {
  110. return Task.FromResult(Insert(entity));
  111. }
  112. public virtual TPrimaryKey InsertAndGetId(TEntity entity)
  113. {
  114. return Insert(entity).Id;
  115. }
  116. public virtual Task<TPrimaryKey> InsertAndGetIdAsync(TEntity entity)
  117. {
  118. return Task.FromResult(InsertAndGetId(entity));
  119. }
  120. public virtual TEntity InsertOrUpdate(TEntity entity)
  121. {
  122. return entity.IsTransient()
  123. ? Insert(entity)
  124. : Update(entity);
  125. }
  126. public virtual async Task<TEntity> InsertOrUpdateAsync(TEntity entity)
  127. {
  128. return entity.IsTransient()
  129. ? await InsertAsync(entity)
  130. : await UpdateAsync(entity);
  131. }
  132. public virtual TPrimaryKey InsertOrUpdateAndGetId(TEntity entity)
  133. {
  134. return InsertOrUpdate(entity).Id;
  135. }
  136. public virtual Task<TPrimaryKey> InsertOrUpdateAndGetIdAsync(TEntity entity)
  137. {
  138. return Task.FromResult(InsertOrUpdateAndGetId(entity));
  139. }
  140. public abstract TEntity Update(TEntity entity);
  141. public virtual Task<TEntity> UpdateAsync(TEntity entity)
  142. {
  143. return Task.FromResult(Update(entity));
  144. }
  145. public virtual TEntity Update(TPrimaryKey id, Action<TEntity> updateAction)
  146. {
  147. var entity = Get(id);
  148. updateAction(entity);
  149. return entity;
  150. }
  151. public virtual async Task<TEntity> UpdateAsync(TPrimaryKey id, Func<TEntity, Task> updateAction)
  152. {
  153. var entity = await GetAsync(id);
  154. await updateAction(entity);
  155. return entity;
  156. }
  157. public abstract void Delete(TEntity entity);
  158. public virtual Task DeleteAsync(TEntity entity)
  159. {
  160. Delete(entity);
  161. return Task.FromResult(0);
  162. }
  163. public abstract void Delete(TPrimaryKey id);
  164. public virtual Task DeleteAsync(TPrimaryKey id)
  165. {
  166. Delete(id);
  167. return Task.FromResult(0);
  168. }
  169. public virtual void Delete(Expression<Func<TEntity, bool>> predicate)
  170. {
  171. foreach (var entity in GetAll().Where(predicate).ToList())
  172. {
  173. Delete(entity);
  174. }
  175. }
  176. public virtual Task DeleteAsync(Expression<Func<TEntity, bool>> predicate)
  177. {
  178. Delete(predicate);
  179. return Task.FromResult(0);
  180. }
  181. public virtual int Count()
  182. {
  183. return GetAll().Count();
  184. }
  185. public virtual Task<int> CountAsync()
  186. {
  187. return Task.FromResult(Count());
  188. }
  189. public virtual int Count(Expression<Func<TEntity, bool>> predicate)
  190. {
  191. return GetAll().Where(predicate).Count();
  192. }
  193. public virtual Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate)
  194. {
  195. return Task.FromResult(Count(predicate));
  196. }
  197. public virtual long LongCount()
  198. {
  199. return GetAll().LongCount();
  200. }
  201. public virtual Task<long> LongCountAsync()
  202. {
  203. return Task.FromResult(LongCount());
  204. }
  205. public virtual long LongCount(Expression<Func<TEntity, bool>> predicate)
  206. {
  207. return GetAll().Where(predicate).LongCount();
  208. }
  209. public virtual Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate)
  210. {
  211. return Task.FromResult(LongCount(predicate));
  212. }
  213. protected virtual Expression<Func<TEntity, bool>> CreateEqualityExpressionForId(TPrimaryKey id)
  214. {
  215. var lambdaParam = Expression.Parameter(typeof(TEntity));
  216. var lambdaBody = Expression.Equal(
  217. Expression.PropertyOrField(lambdaParam, "Id"),
  218. Expression.Constant(id, typeof(TPrimaryKey))
  219. );
  220. return Expression.Lambda<Func<TEntity, bool>>(lambdaBody, lambdaParam);
  221. }
  222. }
  223. }