IQueryableExtensions.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Reflection;
  6. using System.Data;
  7. using System.Collections;
  8. using Bowin.Common.Utility;
  9. using Microsoft.EntityFrameworkCore;
  10. using Microsoft.EntityFrameworkCore.Metadata.Conventions;
  11. using Newtonsoft.Json.Linq;
  12. using Newtonsoft.Json;
  13. namespace Bowin.Common.Linq.Entity
  14. {
  15. /// <summary>
  16. /// Helper extensions for add IDbSet methods defined only
  17. /// for DbSet and ObjectQuery
  18. /// </summary>
  19. public static class IQueryableExtensions
  20. {
  21. /// <summary>
  22. /// 映射。
  23. /// </summary>
  24. /// <typeparam name="TSource"></typeparam>
  25. /// <param name="queryable"></param>
  26. /// <returns></returns>
  27. public static ExpressionFactory<TSource> Map<TSource>(this IQueryable<TSource> queryable)
  28. {
  29. return new ExpressionFactory<TSource>(queryable);
  30. }
  31. public static IGridResultSet<TEntity> ToGridResultSet<TEntity>(this IOrderedEnumerable<TEntity> dataSource, int? pageIndex = null, int? pageSize = null)
  32. {
  33. if (pageIndex.HasValue && pageSize.HasValue)
  34. {
  35. return new GridResultSet<TEntity>
  36. {
  37. rows = dataSource.Skip((pageIndex.Value - 1) * pageSize.Value).Take(pageSize.Value).ToList(),
  38. total = dataSource.Count()
  39. };
  40. }
  41. else
  42. {
  43. var result = new GridResultSet<TEntity>
  44. {
  45. rows = dataSource.ToList()
  46. };
  47. result.total = result.rows.Count;
  48. return result;
  49. }
  50. }
  51. public static IGridResultSet<TEntity> ToGridResultSet<TEntity>(this IOrderedQueryable<TEntity> dataSource, int? pageIndex = null, int? pageSize = null)
  52. {
  53. if (pageIndex.HasValue && pageSize.HasValue)
  54. {
  55. return new GridResultSet<TEntity>
  56. {
  57. rows = dataSource.Skip((pageIndex.Value - 1) * pageSize.Value).Take(pageSize.Value).ToList(),
  58. //rows = dataSource.Select((x, i) => new { RowNumber = i, Data = x })
  59. // .Where(x => x.RowNumber > pageIndex.Value * pageSize.Value).Take(pageSize.Value).Select(x => x.Data).ToList(),
  60. total = dataSource.Count()
  61. };
  62. }
  63. else
  64. {
  65. var result = new GridResultSet<TEntity>
  66. {
  67. rows = dataSource.ToList()
  68. };
  69. result.total = result.rows.Count;
  70. return result;
  71. }
  72. }
  73. public static IGridResultSet<TEntity> ToGridResultSet<TEntity>(this IQueryable<TEntity> dataSource, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderByAction, int? pageIndex = null, int? pageSize = null)
  74. {
  75. if (pageIndex.HasValue && pageSize.HasValue)
  76. {
  77. return new GridResultSet<TEntity>
  78. {
  79. rows = orderByAction.Invoke(orderByAction.Invoke(dataSource).Skip((pageIndex.Value - 1) * pageSize.Value).Take(pageSize.Value)).ToList(),
  80. //rows = dataSource.Select((x, i) => new { RowNumber = i, Data = x })
  81. // .Where(x => x.RowNumber > pageIndex.Value * pageSize.Value).Take(pageSize.Value).Select(x => x.Data).ToList(),
  82. total = dataSource.Count()
  83. };
  84. }
  85. else
  86. {
  87. var result = new GridResultSet<TEntity>
  88. {
  89. rows = dataSource.ToList()
  90. };
  91. result.total = result.rows.Count;
  92. return result;
  93. }
  94. }
  95. public static List<TResult> GridResultSetJoin<TEntity, TInner, TKey, TResult>(this IQueryable<TEntity> dataSource, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderByAction,
  96. IQueryable<TInner> innerQueryable, Expression<Func<TEntity, TKey>> innerKeySelector, Expression<Func<TInner, TKey>> outerKeySelector, Expression<Func<TEntity, TInner, TResult>> resultSelector,
  97. int? pageIndex = null, int? pageSize = null)
  98. {
  99. if (pageIndex.HasValue && pageSize.HasValue)
  100. {
  101. return orderByAction.Invoke(orderByAction.Invoke(dataSource).Skip((pageIndex.Value - 1) * pageSize.Value).Take(pageSize.Value))
  102. .Join(innerQueryable, innerKeySelector, outerKeySelector, resultSelector).ToList();
  103. }
  104. else
  105. {
  106. return dataSource.Join(innerQueryable, innerKeySelector, outerKeySelector, resultSelector).ToList();
  107. }
  108. }
  109. public static IGridResultSet<JObject> ToJsonResultSet<TEntity>(this IOrderedQueryable<TEntity> dataSource, int? pageIndex = null, int? pageSize = null)
  110. {
  111. var resultSet = ToGridResultSet(dataSource, pageIndex, pageSize);
  112. return new GridResultSet<JObject>
  113. {
  114. rows = resultSet.rows.Select(x => JObject.FromObject(x)).ToList(),
  115. total = resultSet.total
  116. };
  117. }
  118. public static IQueryable<TEntity> DynamicWhere<TEntity>(this IQueryable<TEntity> dataSource, string propertyName, string comparer, object value)
  119. {
  120. ExpressionFactory<TEntity> factory = new ExpressionFactory<TEntity>(dataSource);
  121. return dataSource.Where(factory.DynamicExpression(propertyName, comparer, value));
  122. }
  123. public static IQueryable<TEntity> DynamicInWhere<TEntity, TListType>(this IQueryable<TEntity> dataSource, string propertyName, IList<TListType> value)
  124. {
  125. ExpressionFactory<TEntity> factory = new ExpressionFactory<TEntity>(dataSource);
  126. return dataSource.Where(factory.DynamicInExpression(propertyName, value));
  127. }
  128. public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool ascending) where T : class
  129. {
  130. Type type = typeof(T);
  131. PropertyInfo property = type.GetProperty(propertyName);
  132. if (property == null)
  133. throw new ArgumentException("propertyName", "Not Exist");
  134. ParameterExpression param = Expression.Parameter(type, "p");
  135. Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
  136. LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param);
  137. string methodName = ascending ? "OrderBy" : "OrderByDescending";
  138. MethodCallExpression exp = Expression.Call(
  139. typeof(Queryable)
  140. , methodName
  141. , new Type[] { type, property.PropertyType }
  142. , source.Expression
  143. , Expression.Quote(orderByExpression));
  144. return source.Provider.CreateQuery<T>(exp);
  145. }
  146. public static IQueryable<T> ThenBy<T>(this IQueryable<T> source, string propertyName, bool ascending) where T : class
  147. {
  148. Type type = typeof(T);
  149. PropertyInfo property = type.GetProperty(propertyName);
  150. if (property == null)
  151. throw new ArgumentException("propertyName", "Not Exist");
  152. ParameterExpression param = Expression.Parameter(type, "p");
  153. Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
  154. LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param);
  155. string methodName = ascending ? "ThenBy" : "ThenByDescending";
  156. MethodCallExpression exp = Expression.Call(
  157. typeof(Queryable)
  158. , methodName
  159. , new Type[] { type, property.PropertyType }
  160. , source.Expression
  161. , Expression.Quote(orderByExpression));
  162. return source.Provider.CreateQuery<T>(exp);
  163. }
  164. /// <summary>
  165. /// 将集合类转换成DataTable
  166. /// </summary>
  167. /// <param name="list">集合</param>
  168. /// <returns></returns>
  169. public static DataTable ToDataTable<T>(this List<T> list)
  170. {
  171. DataTable result = new DataTable();
  172. if (list.Count > 0)
  173. {
  174. PropertyInfo[] propertys = list[0].GetType().GetProperties();
  175. foreach (PropertyInfo pi in propertys)
  176. {
  177. result.Columns.Add(pi.Name, pi.PropertyType);
  178. }
  179. for (int i = 0; i < list.Count; i++)
  180. {
  181. ArrayList tempList = new ArrayList();
  182. foreach (PropertyInfo pi in propertys)
  183. {
  184. object obj = pi.GetValue(list[i], null);
  185. tempList.Add(obj);
  186. }
  187. object[] array = tempList.ToArray();
  188. result.LoadDataRow(array, true);
  189. }
  190. }
  191. return result;
  192. }
  193. }
  194. }