using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace SqlSugar { /// /// ** description:Get subquery sql /// ** author:sunkaixuan /// ** date:2017/9/17 /// ** email:610262374@qq.com /// public class SubResolve { List allMethods = new List(); private ExpressionContext context = null; private bool hasWhere; public SubResolve(MethodCallExpression expression, ExpressionContext context, Expression oppsiteExpression) { this.context = context; var currentExpression = expression; allMethods.Add(currentExpression); if (context.IsSingle && oppsiteExpression != null && oppsiteExpression is MemberExpression) { var childExpression = (oppsiteExpression as MemberExpression).Expression; if (childExpression is ParameterExpression) this.context.SingleTableNameSubqueryShortName = (childExpression as ParameterExpression).Name; else { this.context.SingleTableNameSubqueryShortName = (context.Expression as LambdaExpression).Parameters.First().Name; } } else if (context.IsSingle) { if (context.Expression is LambdaExpression) { this.context.SingleTableNameSubqueryShortName = (context.Expression as LambdaExpression).Parameters.First().Name; } else if (context.Expression is MethodCallExpression) { var meExp = ((context.Expression as MethodCallExpression).Object as MethodCallExpression).Arguments[0] as LambdaExpression; var selfParameterName = meExp.Parameters.First().Name; context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Left as MemberExpression).Expression as ParameterExpression).Name; if (context.SingleTableNameSubqueryShortName == selfParameterName) { context.SingleTableNameSubqueryShortName = (((meExp.Body as BinaryExpression).Right as MemberExpression).Expression as ParameterExpression).Name; } } else { Check.Exception(true, "I'm sorry I can't parse the current expression"); } } while (currentExpression != null) { var addItem = currentExpression.Object as MethodCallExpression; if (addItem != null) allMethods.Add(addItem); currentExpression = addItem; } } public string GetSql() { var subItems = GetSubItems(); var sql = string.Join(UtilConstants.Space, subItems); return this.context.DbMehtods.Pack(sql); } private List GetSubItems() { var isubList = this.allMethods.Select(exp => { var methodName = exp.Method.Name; var items = SubTools.SubItems(this.context); var item = items.First(s => s.Name == methodName); if (item is SubWhere && !hasWhere) { hasWhere = true; } else if (item is SubWhere) { item = items.First(s => s is SubAnd); } item.Context = this.context; item.Expression = exp; return item; }).ToList(); isubList.Insert(0, new SubBegin()); if (isubList.Any(it => it is SubSelect)) { isubList.Add(new SubTop { Context = this.context }); } if (isubList.Any(it => it is SubAny || it is SubNotAny)) { isubList.Add(new SubLeftBracket()); isubList.Add(new SubRightBracket()); isubList.Add(new SubSelectDefault()); } isubList = isubList.OrderBy(it => it.Sort).ToList(); var result = isubList.Select(it => { return it.GetValue(it.Expression); }).ToList(); return result; } } }