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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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.PartialObjectCopier;
  11. using Luticate2.Auth.Utils.Dbo.Result;
  12. using Luticate2.Auth.Utils.Interfaces;
  13. using Microsoft.EntityFrameworkCore;
  14. using Microsoft.Extensions.DependencyInjection;
  15. namespace Luticate2.Auth.Utils.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 LuConvertersOptions
  74. {
  75. Parameters = new Dictionary<ParameterExpression, Expression>(), // TODO
  76. TypeConverter = null // TODO
  77. };
  78. var converter = new LuExpressionConverterVisitor(options, ServiceProvider);
  79. var lamdbaModel = converter.Visit(lamdbaDbo) as Expression<Func<TModel, bool>>;// TODO Handle errors
  80. return LuResult<IQueryable<TModel>>.Ok(queryable.Where(lamdbaModel));
  81. }
  82. protected virtual LuResult<IQueryable<TModel>> OrderByField(LuOrderByFieldDbo orderByfield, IQueryable<TModel> queryable)
  83. {
  84. // var expressionBuilder = ServiceProvider.GetService<ILuDboModelExpressionConverter<TDbo, TModel>>();
  85. // var expressionResult = expressionBuilder.ConvertLamdba<TModel>(orderByfield.);
  86. // if (!expressionResult)
  87. // {
  88. // return expressionResult.To<IQueryable<TModel>>();
  89. // }
  90. //
  91. // var expression = expressionResult.Data;
  92. // var expressionNoConvert = LuExpressionUtils.GetFromConvert(expression);
  93. //
  94. // var ordered = queryable.OrderBy(expressionNoConvert);
  95. //
  96. // return LuResult<IQueryable<TModel>>.Ok(ordered);
  97. return LuResult<IQueryable<TModel>>.Ok(queryable);
  98. }
  99. protected virtual LuResult<IQueryable<TModel>> OrderBy(LuOrderByDbo orderBy, IQueryable<TModel> queryable)
  100. {
  101. var ordered = queryable;
  102. foreach (var field in orderBy.OrderByFields)
  103. {
  104. var orderedResult = OrderByField(field, ordered);
  105. if (!orderedResult)
  106. {
  107. return orderedResult.To<IQueryable<TModel>>();
  108. }
  109. ordered = orderedResult.Data;
  110. }
  111. return LuResult<IQueryable<TModel>>.Ok(ordered ?? queryable);
  112. }
  113. protected virtual LuResult<IQueryable<TModel>> Paginate(int page, int perPage, IQueryable<TModel> queryable)
  114. {
  115. var paginated = queryable.Skip(page * perPage).Take(perPage);
  116. return LuResult<IQueryable<TModel>>.Ok(paginated);
  117. }
  118. public virtual LuResult<IList<TDbo>> Create(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
  119. {
  120. throw new NotImplementedException();
  121. }
  122. public virtual LuResult<LuPaginatedDbo<TDbo>> Read(LuPartialFieldsDbo partialResponse, LuPaginatedParamsDbo paginationParams)
  123. {
  124. var result = Execute((context, set) =>
  125. {
  126. var includeResult = Include(partialResponse, set);
  127. if (!includeResult)
  128. {
  129. return includeResult.To<LuPaginatedDbo<TDbo>>();
  130. }
  131. var included = includeResult.Data;
  132. var orderByResult = OrderBy(paginationParams.OrderBy, included);
  133. if (!orderByResult)
  134. {
  135. return orderByResult.To<LuPaginatedDbo<TDbo>>();
  136. }
  137. var ordered = orderByResult.Data;
  138. var filteredResult = Filter(paginationParams.Filter, ordered);
  139. if (!filteredResult)
  140. {
  141. return filteredResult.To<LuPaginatedDbo<TDbo>>();
  142. }
  143. var filtered = filteredResult.Data;
  144. var count = filtered.Count();
  145. var paginatedResult = Paginate(paginationParams.Page, paginationParams.PerPage, filtered);
  146. if (!paginatedResult)
  147. {
  148. return paginatedResult.To<LuPaginatedDbo<TDbo>>();
  149. }
  150. var paginated = paginatedResult.Data;
  151. var data = paginated.AsEnumerable().Select(model =>
  152. {
  153. var dbo = new TDbo();
  154. ConvertModelToDbo(partialResponse, model, dbo);
  155. return dbo;
  156. }).ToList();
  157. return LuResult<LuPaginatedDbo<TDbo>>.Ok(new LuPaginatedDbo<TDbo>
  158. {
  159. Count = count,
  160. Data = data
  161. });
  162. });
  163. return result;
  164. }
  165. public virtual LuResult<IList<TDbo>> Update(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
  166. {
  167. throw new NotImplementedException();
  168. }
  169. public virtual LuResult<IList<TDbo>> Delete(LuPartialFieldsDbo partialResponse, LuPartialFieldsDbo partialInput, IEnumerable<TDbo> dbos)
  170. {
  171. throw new NotImplementedException();
  172. }
  173. }
  174. }