/// <summary> /// 初始化 <see cref="AggregateExpressionVisitor"/> 类的新实例 /// </summary> public AggregateExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, DbExpression aggregate, DbExpression groupBy = null, string alias = null) : base(provider, aliases, aggregate.Expressions != null ? aggregate.Expressions[0] : null, false) { _provider = provider; _aliases = aliases; _aggregate = aggregate; _groupBy = groupBy; _alias = alias; }
// 解析查询语义 static IDbQueryableInfo <TElement> Parse <TElement>(IDbQueryable <TElement> dbQuery, int startIndex) { // 目的:将query 转换成增/删/改/查 // 1、from a in context.GetTable<T>() select a 此时query里面可能没有SELECT 表达式 // 2、Take 视为一个查询的结束位,如有更多查询,应使用嵌套查询 // 3、uion 分页查询也使嵌套语义 // 4、uion 后面跟着 WHERE,GROUP BY,SELECT,JOIN语句时需要使用嵌套查询 Type type = null; bool isDistinct = false; bool isAny = false; bool subQuery = false; int? skip = null; int? take = null; int? outerIndex = null; var whereExpressions = new List <Expression>(); // WHERE var havingExpressions = new List <Expression>(); // HAVING var joins = new List <DbExpression>(); // JOIN var orderBys = new List <DbExpression>(); // ORDER BY var includes = new List <DbExpression>(); // ORDER BY var unions = new List <IDbQueryableInfo <TElement> >(); Expression selectExpression = null; // SELECT # DbExpression insertExpression = null; // INSERT # DbExpression updateExpression = null; // UPDATE # DbExpression deleteExpression = null; // DELETE # DbExpression groupByExpression = null; // GROUP BY # DbExpression statisExpression = null; // SUM/MAX # for (int index = startIndex; index < dbQuery.DbExpressions.Count; index++) { DbExpression curExpr = dbQuery.DbExpressions[index]; // Take(n) if (take != null || (skip != null && curExpr.DbExpressionType != DbExpressionType.Take) || isDistinct || subQuery) { outerIndex = index; break; } #region 解析片断 switch (curExpr.DbExpressionType) { case DbExpressionType.None: case DbExpressionType.All: continue; case DbExpressionType.Any: isAny = true; if (curExpr.Expressions != null) { whereExpressions.Add(curExpr.Expressions[0]); } break; case DbExpressionType.AsSubQuery: subQuery = true; continue; case DbExpressionType.Union: var uQuery = (curExpr.Expressions[0] as ConstantExpression).Value as IDbQueryable <TElement>; var u = DbQueryParser.Parse(uQuery); unions.Add(u); // 如果下一个不是 union,就使用嵌套 if (index + 1 <= dbQuery.DbExpressions.Count - 1 && dbQuery.DbExpressions[index + 1].DbExpressionType != DbExpressionType.Union) { subQuery = true; } continue; case DbExpressionType.Include: includes.Add(curExpr); continue; case DbExpressionType.GroupBy: groupByExpression = curExpr; continue; case DbExpressionType.GetTable: type = (curExpr.Expressions[0] as ConstantExpression).Value as Type; continue; case DbExpressionType.Average: case DbExpressionType.Min: case DbExpressionType.Sum: case DbExpressionType.Max: statisExpression = curExpr; continue; case DbExpressionType.Count: statisExpression = curExpr; if (curExpr.Expressions != null) { whereExpressions.Add(curExpr.Expressions[0]); } continue; case DbExpressionType.Distinct: isDistinct = true; continue; case DbExpressionType.First: case DbExpressionType.FirstOrDefault: take = 1; if (curExpr.Expressions != null) { whereExpressions.Add(curExpr.Expressions[0]); } continue; case DbExpressionType.Join: case DbExpressionType.GroupJoin: case DbExpressionType.GroupRightJoin: selectExpression = curExpr.Expressions[3]; joins.Add(curExpr); continue; case DbExpressionType.OrderBy: case DbExpressionType.OrderByDescending: orderBys.Add(curExpr); continue; case DbExpressionType.Select: selectExpression = curExpr.Expressions != null ? curExpr.Expressions[0] : null; continue; case DbExpressionType.SelectMany: selectExpression = curExpr.Expressions[1]; if (IsSelectMany(dbQuery.DbExpressions, curExpr, startIndex)) { joins.Add(curExpr); } continue; case DbExpressionType.Single: case DbExpressionType.SingleOrDefault: take = 1; if (curExpr.Expressions != null) { whereExpressions.Add(curExpr.Expressions[0]); } continue; case DbExpressionType.Skip: skip = (int)(curExpr.Expressions[0] as ConstantExpression).Value; continue; case DbExpressionType.Take: take = (int)(curExpr.Expressions[0] as ConstantExpression).Value; continue; case DbExpressionType.ThenBy: case DbExpressionType.ThenByDescending: orderBys.Add(curExpr); continue; case DbExpressionType.Where: var predicate = groupByExpression == null ? whereExpressions : havingExpressions; if (curExpr.Expressions != null) { predicate.Add(curExpr.Expressions[0]); } continue; case DbExpressionType.Insert: insertExpression = curExpr; continue; case DbExpressionType.Update: updateExpression = curExpr; continue; case DbExpressionType.Delete: deleteExpression = curExpr; continue; default: throw new NotSupportedException(string.Format("{0} is not support.", curExpr.DbExpressionType)); } #endregion } // 没有解析到INSERT/DELETE/UPDATE/SELECT表达式,并且没有相关统计函数,则默认选择FromType的所有字段 bool useFullFields = insertExpression == null && deleteExpression == null && updateExpression == null && selectExpression == null && statisExpression == null; if (useFullFields) { selectExpression = Expression.Constant(type ?? typeof(TElement)); } var sQueryInfo = new DbQueryableInfo_Select <TElement>(); sQueryInfo.FromType = type; sQueryInfo.HasDistinct = isDistinct; sQueryInfo.HasAny = isAny; sQueryInfo.Joins = joins; sQueryInfo.OrderBys = orderBys; sQueryInfo.GroupByExpression = groupByExpression; sQueryInfo.StatisExpression = statisExpression; sQueryInfo.Unions = unions; sQueryInfo.Includes = includes; sQueryInfo.Skip = skip != null ? skip.Value : 0; sQueryInfo.Take = take != null ? take.Value : 0; sQueryInfo.SelectExpression = new DbExpression(DbExpressionType.Select, selectExpression); sQueryInfo.WhereExpression = new DbExpression(DbExpressionType.Where, CombineWhere(whereExpressions)); sQueryInfo.HavingExpression = new DbExpression(DbExpressionType.None, CombineWhere(havingExpressions)); sQueryInfo.SourceQuery = dbQuery; #region 更新语义 if (updateExpression != null) { var uQueryInfo = new DbQueryableInfo_Update <TElement>(); var constantExpression = updateExpression.Expressions != null ? updateExpression.Expressions[0] as ConstantExpression : null; if (constantExpression != null) { uQueryInfo.Entity = constantExpression.Value; } else { uQueryInfo.Expression = updateExpression.Expressions[0]; } uQueryInfo.SelectInfo = sQueryInfo; uQueryInfo.SourceQuery = dbQuery; return(uQueryInfo); } #endregion #region 除语义 else if (deleteExpression != null) { var dQueryInfo = new DbQueryableInfo_Delete <TElement>(); var constantExpression = deleteExpression.Expressions != null ? deleteExpression.Expressions[0] as ConstantExpression : null; if (constantExpression != null) { dQueryInfo.Entity = constantExpression.Value; } dQueryInfo.SelectInfo = sQueryInfo; dQueryInfo.SourceQuery = dbQuery; return(dQueryInfo); } #endregion #region 插入语义 else if (insertExpression != null) { var nQueryInfo = new DbQueryableInfo_Insert <TElement>(); if (insertExpression.Expressions != null) { nQueryInfo.Entity = (insertExpression.Expressions[0] as ConstantExpression).Value; if (insertExpression.Expressions.Length > 1) { nQueryInfo.EntityColumns = (insertExpression.Expressions[1] as ConstantExpression).Value as IList <Expression>; } } nQueryInfo.SelectInfo = sQueryInfo; nQueryInfo.Bulk = dbQuery.Bulk; nQueryInfo.SourceQuery = dbQuery; dbQuery.DbQueryInfo = nQueryInfo; return(nQueryInfo); } #endregion #region 择语义 else if (selectExpression != null) { // 检查嵌套查询语义 sQueryInfo = DbQueryParser.TryBuildOutQuery(sQueryInfo); // 查询来源 sQueryInfo.SourceQuery = dbQuery; } #endregion #region 嵌套语义 // 解析嵌套查询 if (outerIndex != null) { var outQuery = DbQueryParser.Parse <TElement>(dbQuery, outerIndex.Value); var nQuery = outQuery as DbQueryableInfo_Insert <TElement>; var uQuery = outQuery as DbQueryableInfo_Update <TElement>; if (nQuery != null) { if (nQuery.SelectInfo != null) { nQuery.SelectInfo.SubQueryInfo = sQueryInfo; } else { nQuery.SelectInfo = sQueryInfo; } nQuery.SourceQuery = dbQuery; return(nQuery); } else if (uQuery != null) { if (uQuery.SelectInfo != null) { uQuery.SelectInfo.SubQueryInfo = sQueryInfo; } else { uQuery.SelectInfo = sQueryInfo; } uQuery.SourceQuery = dbQuery; return(uQuery); } else { var rootQuery = outQuery; while (rootQuery.SubQueryInfo != null) { rootQuery = rootQuery.SubQueryInfo; } rootQuery.SubQueryInfo = sQueryInfo; outQuery.SourceQuery = dbQuery; // 如果外层是统计,内层没有分页,则不需要排序 rootQuery = outQuery; while (rootQuery.SubQueryInfo != null) { var myOutQuery = rootQuery as IDbQueryableInfo_Select; var mySubQuery = rootQuery.SubQueryInfo as IDbQueryableInfo_Select; // 没有分页的嵌套统计,不需要排序 if (myOutQuery.StatisExpression != null && !(mySubQuery.Take > 0 || mySubQuery.Skip > 0) && mySubQuery.OrderBys.Count > 0) { mySubQuery.OrderBys = new List <DbExpression>(0); } // 继续下一轮迭代 rootQuery = rootQuery.SubQueryInfo; } return(outQuery); } } #endregion // 查询表达式 return(sQueryInfo); }
/// <summary> /// 初始化 <see cref="StatisExpressionVisitor"/> 类的新实例 /// </summary> public StatisExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, DbExpression statis, DbExpression groupBy = null, string alias = null) : base(provider, aliases, statis.Expressions != null ? statis.Expressions[0] : null, false) { _provider = provider; _aliases = aliases; _statis = statis; _groupBy = groupBy; _alias = alias; }