SubFirst.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace SqlSugar
  8. {
  9. public class SubFirst : ISubOperation
  10. {
  11. public bool HasWhere
  12. {
  13. get; set;
  14. }
  15. public string Name
  16. {
  17. get
  18. {
  19. return "First";
  20. }
  21. }
  22. public Expression Expression
  23. {
  24. get; set;
  25. }
  26. public int Sort
  27. {
  28. get
  29. {
  30. return 200;
  31. }
  32. }
  33. public ExpressionContext Context
  34. {
  35. get; set;
  36. }
  37. public string GetValue(Expression expression = null)
  38. {
  39. var exp = expression as MethodCallExpression;
  40. if (IsAutoGeneric(exp)) return GetValueByAuto(exp);
  41. if (IsAutoSelect(exp)) return GetValueByAuto(exp);
  42. InitType(exp);
  43. var type = expression.Type;
  44. if (type.FullName.IsCollectionsList()
  45. && exp.Arguments.Count == 0 && type.GenericTypeArguments.Length > 0
  46. && this.Context.SugarContext != null
  47. && this.Context.SugarContext.QueryBuilder.IsSelectNoAll)
  48. {
  49. var entity = type.GenericTypeArguments[0];
  50. var columnNames = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(entity).Columns;
  51. var columnsString = string.Join(",", columnNames
  52. .Where(it => it.IsIgnore == false)
  53. .Where(it => it.DbColumnName.HasValue())
  54. .Select(it => this.Context.GetTranslationColumnName(it.DbColumnName)));
  55. return $"{columnsString},@sugarIndex as sugarIndex";
  56. }
  57. else if (exp.Arguments.Count == 0)
  58. {
  59. return "*,@sugarIndex as sugarIndex";
  60. }
  61. var argExp = exp.Arguments[0];
  62. var parametres = (argExp as LambdaExpression).Parameters;
  63. if ((argExp as LambdaExpression).Body is UnaryExpression)
  64. {
  65. argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand;
  66. }
  67. var argLambda = argExp as LambdaExpression;
  68. var copyContext = this.Context.GetCopyContextWithMapping();
  69. copyContext.Resolve(argLambda, ResolveExpressType.SelectMultiple);
  70. var select = copyContext.Result.GetString();
  71. this.Context.Parameters.AddRange(copyContext.Parameters);
  72. this.Context.Index = copyContext.Index;
  73. this.Context.ParameterIndex = copyContext.ParameterIndex;
  74. SetShortName(exp, null);
  75. return select + ",@sugarIndex as sugarIndex";
  76. }
  77. private void InitType(MethodCallExpression exp)
  78. {
  79. if (exp.Arguments.Count > 0)
  80. {
  81. foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters)
  82. {
  83. if (this.Context.InitMappingInfo != null)
  84. {
  85. this.Context.InitMappingInfo(arg.Type);
  86. this.Context.RefreshMapping();
  87. }
  88. }
  89. }
  90. }
  91. public void SetShortName(MethodCallExpression exp, string result)
  92. {
  93. if (exp.Arguments.Any()&&exp.Arguments[0] is LambdaExpression)
  94. {
  95. var parameters = (exp.Arguments[0] as LambdaExpression).Parameters;
  96. if (parameters != null && parameters.Count > 0)
  97. {
  98. this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString());
  99. }
  100. }
  101. }
  102. public void SetShortNameNext(MethodCallExpression exp, string result)
  103. {
  104. if (exp.Arguments.Count > 1 && exp.Arguments[1] is LambdaExpression)
  105. {
  106. var parameters = (exp.Arguments[1] as LambdaExpression).Parameters;
  107. if (parameters != null && parameters.Count > 0)
  108. {
  109. this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString());
  110. }
  111. }
  112. }
  113. private string GetValueByAuto(MethodCallExpression exp)
  114. {
  115. var selectExp = exp.Arguments.FirstOrDefault();
  116. if (selectExp == null)
  117. {
  118. var type = exp.Type;
  119. var parameter = Expression.Parameter(type, "it");
  120. // 构造返回值表达式
  121. var body = Expression.MemberInit(Expression.New(type));
  122. // 将返回值表达式作为lambda表达式的主体
  123. selectExp = Expression.Lambda(body, parameter);
  124. }
  125. var bodyExp = ExpressionTool.GetLambdaExpressionBody(selectExp);
  126. var newMemExp = (bodyExp as MemberInitExpression);
  127. var parameters = ExpressionTool.GetParameters(exp);
  128. InitType(exp);
  129. if (parameters.Any())
  130. {
  131. this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters.FirstOrDefault().Name);
  132. }
  133. Check.ExceptionEasy(newMemExp == null, $"Subquery ToList(exp,true) expression {exp.ToString()} can only be it=>new class(){{Id = it.id}}", $"子查询ToList(exp,true)表达式{exp.ToString()}只能是it=>new class(){{ id=it.Id}}");
  134. var dic = ExpressionTool.GetMemberBindingItemList(newMemExp.Bindings);
  135. var db = this.Context.SugarContext.Context;
  136. var builder = this.Context.SugarContext.QueryBuilder.Builder;
  137. var columnInfos = db.EntityMaintenance.GetEntityInfo(bodyExp.Type);
  138. var autoColumns = columnInfos.Columns
  139. .Where(it => !dic.ContainsKey(it.PropertyName))
  140. .Where(it => it.IsIgnore == false)
  141. .ToList();
  142. List<string> appendColumns = new List<string>();
  143. List<string> completeColumnColumns = new List<string>();
  144. foreach (var item in autoColumns)
  145. {
  146. foreach (var parameter in parameters)
  147. {
  148. var parameterColumns = db.EntityMaintenance.GetEntityInfo(parameter.Type).Columns;
  149. if (!completeColumnColumns.Any(it => it.EqualCase(item.PropertyName)) && parameterColumns.Any(it => it.PropertyName.EqualCase(item.PropertyName)))
  150. {
  151. var completeColumn = parameterColumns.First(it => it.PropertyName == item.PropertyName);
  152. var shortName = builder.GetTranslationColumnName(parameter.Name);
  153. var columnName = builder.GetTranslationColumnName(completeColumn.DbColumnName);
  154. var asName = builder.SqlTranslationLeft + item.PropertyName + builder.SqlTranslationRight;
  155. appendColumns.Add($"{shortName}.{columnName} as {asName}");
  156. completeColumnColumns.Add(completeColumn.PropertyName);
  157. }
  158. }
  159. }
  160. var copyContext = this.Context.GetCopyContextWithMapping();
  161. copyContext.Resolve(bodyExp, ResolveExpressType.SelectMultiple);
  162. var select = copyContext.Result.GetString();
  163. if (dic.Count > 0 && appendColumns.Count == 0)
  164. {
  165. return select + ",@sugarIndex as sugarIndex"; ;
  166. }
  167. else if (dic.Count > 0 && appendColumns.Count > 0)
  168. {
  169. return select + "," + string.Join(",", appendColumns) + ",@sugarIndex as sugarIndex"; ;
  170. }
  171. else
  172. {
  173. return string.Join(",", appendColumns) + ",@sugarIndex as sugarIndex";
  174. }
  175. }
  176. private static bool IsAutoSelect(MethodCallExpression exp)
  177. {
  178. return exp.Arguments.Count == 2 && exp.Arguments.Last().Type == UtilConstants.BoolType;
  179. }
  180. private static bool IsAutoGeneric(MethodCallExpression exp)
  181. {
  182. return exp.Arguments.Count == 0 && exp.Method.GetGenericArguments().Count() == 1;
  183. }
  184. }
  185. }