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.8KB

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