You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LuEfCrudBusiness.cs 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using Luticate2.Auth.Utils.Business.Converters;
  6. using Luticate2.Auth.Utils.Business.ExpressionConverter;
  7. using Luticate2.Auth.Utils.Dbo;
  8. using Luticate2.Auth.Utils.Dbo.Fields;
  9. using Luticate2.Auth.Utils.Dbo.Pagination;
  10. using Luticate2.Auth.Utils.Dbo.Result;
  11. using Luticate2.Auth.Utils.Interfaces;
  12. using Microsoft.EntityFrameworkCore;
  13. using Microsoft.Extensions.DependencyInjection;
  14. namespace Luticate2.Auth.Utils.Business.Crud
  15. {
  16. public class LuEfCrudBusiness<TDbo, TModel, TDbContext> : ILuCrud<TDbo>
  17. where TModel : class
  18. where TDbContext : DbContext
  19. where TDbo : class, new()
  20. {
  21. protected IServiceProvider ServiceProvider { get; }
  22. protected ILuConvertersAllocator ConvertersAllocator { get; }
  23. public LuEfCrudBusiness(IServiceProvider serviceProvider)
  24. {
  25. ServiceProvider = serviceProvider;
  26. ConvertersAllocator = ServiceProvider.GetRequiredService<ILuConvertersAllocator>();
  27. }
  28. protected virtual ILuObjectConverterOptions GetOptions()
  29. {
  30. return new LuConvertersOptions
  31. {
  32. Allocator = ConvertersAllocator
  33. };// TODO
  34. }
  35. protected virtual LuResult<TModel> ConvertDboToModel(LuPartialFieldsDbo partialInput, TDbo dbo)
  36. {
  37. var copier = ServiceProvider.GetService<ILuObjectConverter<TDbo, TModel>>();
  38. if (copier == null)
  39. {
  40. return LuResult<TModel>.Error(LuStatus.InternalError.ToInt(),
  41. $"Could not get service: {nameof(ILuObjectConverter)}<{typeof(TDbo).Name}, {typeof(TModel).Name}>");
  42. }
  43. var options = GetOptions();
  44. var dstObj = options.Allocator.GetInstance(typeof(TModel));
  45. var result = copier.Convert(dbo, dstObj, new LuFieldDbo(), partialInput, GetOptions());
  46. return result.Select(o => o as TModel);
  47. }
  48. protected virtual LuResult<TDbo> ConvertModelToDbo(LuPartialFieldsDbo partialResponse, TModel model)
  49. {
  50. var copier = ServiceProvider.GetService<ILuObjectConverter<TModel, TDbo>>();
  51. if (copier == null)
  52. {
  53. return LuResult<TDbo>.Error(LuStatus.InternalError.ToInt(),
  54. $"Could not get service: {nameof(ILuObjectConverter)}<{typeof(TModel).Name}, {typeof(TDbo).Name}>");
  55. }
  56. var options = GetOptions();
  57. var dstObj = options.Allocator.GetInstance(typeof(TDbo));
  58. var result = copier.Convert(model, dstObj, new LuFieldDbo(), partialResponse, GetOptions());
  59. return result.Select(o => o as TDbo);
  60. }
  61. protected virtual LuResult<T> HandleError<T>(Exception e)
  62. {
  63. return LuResult<T>.Error(LuStatus.DbError.ToInt(), e);
  64. }
  65. protected LuResult<T> Execute<T>(Func<TDbContext, DbSet<TModel>, LuResult<T>> action)
  66. {
  67. try
  68. {
  69. using (var db = ServiceProvider.GetService<TDbContext>())
  70. {
  71. return action(db, db.Set<TModel>());
  72. }
  73. }
  74. catch (Exception e)
  75. {
  76. var result = HandleError<T>(e);
  77. return result;
  78. }
  79. }
  80. protected virtual LuResult<IQueryable<TModel>> Include(LuPartialFieldsDbo partialResponse, IQueryable<TModel> queryable)
  81. {
  82. return LuResult<IQueryable<TModel>>.Ok(queryable);
  83. }
  84. protected virtual LuResult<IQueryable<TModel>> Filter(LuFilterDbo filter, IQueryable<TModel> queryable)
  85. {
  86. var lamdbaDbo = (Expression<Func<TDbo, bool>>) filter.Expression;
  87. var options = new LuConvertersOptions
  88. {
  89. Parameters = new Dictionary<ParameterExpression, Expression>(), // TODO
  90. TypeConverter = null, // TODO
  91. Allocator = ConvertersAllocator
  92. };
  93. var converter = new LuExpressionConverterVisitor(options, ServiceProvider);
  94. var lamdbaModel = converter.Visit(lamdbaDbo) as Expression<Func<TModel, bool>>;// TODO Handle errors
  95. return LuResult<IQueryable<TModel>>.Ok(queryable.Where(lamdbaModel));
  96. }
  97. protected virtual LuResult<IQueryable<TModel>> OrderByField(LuOrderByFieldDbo orderByfield, IQueryable<TModel> queryable)
  98. {
  99. // var expressionBuilder = ServiceProvider.GetService<ILuDboModelExpressionConverter<TDbo, TModel>>();
  100. // var expressionResult = expressionBuilder.ConvertLamdba<TModel>(orderByfield.);
  101. // if (!expressionResult)
  102. // {
  103. // return expressionResult.To<IQueryable<TModel>>();
  104. // }
  105. //
  106. // var expression = expressionResult.Data;
  107. // var expressionNoConvert = LuExpressionUtils.GetFromConvert(expression);
  108. //
  109. // var ordered = queryable.OrderBy(expressionNoConvert);
  110. //
  111. // return LuResult<IQueryable<TModel>>.Ok(ordered);
  112. return LuResult<IQueryable<TModel>>.Ok(queryable);
  113. }
  114. protected virtual LuResult<IQueryable<TModel>> OrderBy(LuOrderByDbo orderBy, IQueryable<TModel> queryable)
  115. {
  116. var ordered = queryable;
  117. foreach (var field in orderBy.OrderByFields)
  118. {
  119. var orderedResult = OrderByField(field, ordered);
  120. if (!orderedResult)
  121. {
  122. return orderedResult.To<IQueryable<TModel>>();
  123. }
  124. ordered = orderedResult.Data;
  125. }
  126. return LuResult<IQueryable<TModel>>.Ok(ordered ?? queryable);
  127. }
  128. protected virtual LuResult<IQueryable<TModel>> Paginate(int page, int perPage, IQueryable<TModel> queryable)
  129. {
  130. var paginated = queryable.Skip(page * perPage).Take(perPage);
  131. return LuResult<IQueryable<TModel>>.Ok(paginated);
  132. }
  133. public virtual LuResult<IList<TDbo>> Create(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
  134. {
  135. throw new NotImplementedException();
  136. }
  137. public virtual LuResult<LuPaginatedDbo<TDbo>> Read(LuPartialFieldsDbo partialResponse, LuPaginatedParamsDbo paginationParams)
  138. {
  139. var result = Execute((context, set) =>
  140. {
  141. var includeResult = Include(partialResponse, set);
  142. if (!includeResult)
  143. {
  144. return includeResult.To<LuPaginatedDbo<TDbo>>();
  145. }
  146. var included = includeResult.Data;
  147. var orderByResult = OrderBy(paginationParams.OrderBy, included);
  148. if (!orderByResult)
  149. {
  150. return orderByResult.To<LuPaginatedDbo<TDbo>>();
  151. }
  152. var ordered = orderByResult.Data;
  153. var filteredResult = Filter(paginationParams.Filter, ordered);
  154. if (!filteredResult)
  155. {
  156. return filteredResult.To<LuPaginatedDbo<TDbo>>();
  157. }
  158. var filtered = filteredResult.Data;
  159. var count = filtered.Count();
  160. var paginatedResult = Paginate(paginationParams.Page, paginationParams.PerPage, filtered);
  161. if (!paginatedResult)
  162. {
  163. return paginatedResult.To<LuPaginatedDbo<TDbo>>();
  164. }
  165. var paginated = paginatedResult.Data;
  166. var data = paginated.AsEnumerable().Select(model =>
  167. {
  168. var convertResult = ConvertModelToDbo(partialResponse, model); // TODO Handle error
  169. return convertResult.Data;
  170. }).ToList();
  171. return LuResult<LuPaginatedDbo<TDbo>>.Ok(new LuPaginatedDbo<TDbo>
  172. {
  173. Count = count,
  174. Data = data
  175. });
  176. });
  177. return result;
  178. }
  179. public virtual LuResult<IList<TDbo>> Update(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
  180. {
  181. throw new NotImplementedException();
  182. }
  183. public virtual LuResult<IList<TDbo>> Delete(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
  184. {
  185. throw new NotImplementedException();
  186. }
  187. }
  188. }