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 7.9KB

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