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.

107 lines
4.4 KiB

2 years ago
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Linq.Expressions;
  4. namespace SqlSugar
  5. {
  6. ///<summary>
  7. /// ** description:Get subquery sql
  8. /// ** author:sunkaixuan
  9. /// ** date:2017/9/17
  10. /// ** email:610262374@qq.com
  11. /// </summary>
  12. public class SubResolve
  13. {
  14. List<MethodCallExpression> allMethods = new List<MethodCallExpression>();
  15. private ExpressionContext context = null;
  16. private bool hasWhere;
  17. public SubResolve(MethodCallExpression expression, ExpressionContext context, Expression oppsiteExpression)
  18. {
  19. this.context = context;
  20. var currentExpression = expression;
  21. allMethods.Add(currentExpression);
  22. if (context.IsSingle && oppsiteExpression != null && oppsiteExpression is MemberExpression)
  23. {
  24. var childExpression = (oppsiteExpression as MemberExpression).Expression;
  25. if (childExpression is ParameterExpression)
  26. this.context.SingleTableNameSubqueryShortName = (childExpression as ParameterExpression).Name;
  27. else {
  28. this.context.SingleTableNameSubqueryShortName = (context.Expression as LambdaExpression).Parameters.First().Name;
  29. }
  30. }
  31. else if (context.IsSingle)
  32. {
  33. if (context.Expression is LambdaExpression)
  34. {
  35. this.context.SingleTableNameSubqueryShortName = (context.Expression as LambdaExpression).Parameters.First().Name;
  36. }
  37. else if (context.Expression is MethodCallExpression)
  38. {
  39. var meExp = ((context.Expression as MethodCallExpression).Object as MethodCallExpression).Arguments[0] as LambdaExpression;
  40. var selfParameterName = meExp.Parameters.First().Name;
  41. context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Left as MemberExpression).Expression as ParameterExpression).Name;
  42. if (context.SingleTableNameSubqueryShortName == selfParameterName)
  43. {
  44. context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Right as MemberExpression).Expression as ParameterExpression).Name;
  45. }
  46. }
  47. else
  48. {
  49. Check.Exception(true, "I'm sorry I can't parse the current expression");
  50. }
  51. }
  52. while (currentExpression != null)
  53. {
  54. var addItem = currentExpression.Object as MethodCallExpression;
  55. if (addItem != null)
  56. allMethods.Add(addItem);
  57. currentExpression = addItem;
  58. }
  59. }
  60. public string GetSql()
  61. {
  62. var subItems = GetSubItems();
  63. var sql = string.Join(UtilConstants.Space, subItems);
  64. return this.context.DbMehtods.Pack(sql);
  65. }
  66. private List<string> GetSubItems()
  67. {
  68. var isubList = this.allMethods.Select(exp =>
  69. {
  70. var methodName = exp.Method.Name;
  71. var items = SubTools.SubItems(this.context);
  72. var item = items.First(s => s.Name == methodName);
  73. if (item is SubWhere && !hasWhere)
  74. {
  75. hasWhere = true;
  76. }
  77. else if (item is SubWhere)
  78. {
  79. item = items.First(s => s is SubAnd);
  80. }
  81. item.Context = this.context;
  82. item.Expression = exp;
  83. return item;
  84. }).ToList();
  85. isubList.Insert(0, new SubBegin());
  86. if (isubList.Any(it => it is SubSelect))
  87. {
  88. isubList.Add(new SubTop { Context = this.context });
  89. }
  90. if (isubList.Any(it => it is SubAny || it is SubNotAny))
  91. {
  92. isubList.Add(new SubLeftBracket());
  93. isubList.Add(new SubRightBracket());
  94. isubList.Add(new SubSelectDefault());
  95. }
  96. isubList = isubList.OrderBy(it => it.Sort).ToList();
  97. var result = isubList.Select(it =>
  98. {
  99. return it.GetValue(it.Expression);
  100. }).ToList();
  101. return result;
  102. }
  103. }
  104. }