// 解析查询语义 static IDbQueryableInfo <TElement> Parse <TElement>(IDbQueryable <TElement> source, 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 conditions = new List <Expression>(); // WHERE var havings = 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 select = null; // SELECT # DbExpression insert = null; // INSERT # DbExpression update = null; // UPDATE # DbExpression delete = null; // DELETE # DbExpression group = null; // GROUP BY # DbExpression aggregate = null; // SUM&MAX # for (int index = startIndex; index < source.DbExpressions.Count; index++) { DbExpression item = source.DbExpressions[index]; // Take(n) if (take != null || (skip != null && item.DbExpressionType != DbExpressionType.Take) || isDistinct || subQuery) { outerIndex = index; break; } #region 解析片断 switch (item.DbExpressionType) { case DbExpressionType.None: case DbExpressionType.All: continue; case DbExpressionType.Any: isAny = true; if (item.Expressions != null) { conditions.Add(item.Expressions[0]); } break; case DbExpressionType.AsSubQuery: subQuery = true; continue; case DbExpressionType.Union: var uQuery = (item.Expressions[0] as ConstantExpression).Value as IDbQueryable <TElement>; var u = DbQueryParser.Parse(uQuery); unions.Add(u); // 如果下一个不是 union,就使用嵌套 if (index + 1 <= source.DbExpressions.Count - 1 && source.DbExpressions[index + 1].DbExpressionType != DbExpressionType.Union) { subQuery = true; } continue; case DbExpressionType.Include: includes.Add(item); continue; case DbExpressionType.GroupBy: group = item; continue; case DbExpressionType.GetTable: type = (item.Expressions[0] as ConstantExpression).Value as Type; continue; case DbExpressionType.Average: case DbExpressionType.Min: case DbExpressionType.Sum: case DbExpressionType.Max: aggregate = item; continue; case DbExpressionType.Count: aggregate = item; if (item.Expressions != null) { conditions.Add(item.Expressions[0]); } continue; case DbExpressionType.Distinct: isDistinct = true; continue; case DbExpressionType.First: case DbExpressionType.FirstOrDefault: take = 1; if (item.Expressions != null) { conditions.Add(item.Expressions[0]); } continue; case DbExpressionType.Join: case DbExpressionType.GroupJoin: case DbExpressionType.GroupRightJoin: select = item.Expressions[3]; joins.Add(item); continue; case DbExpressionType.OrderBy: case DbExpressionType.OrderByDescending: orderBys.Add(item); continue; case DbExpressionType.Select: select = item.Expressions != null ? item.Expressions[0] : null; continue; case DbExpressionType.SelectMany: select = item.Expressions[1]; if (IsSelectMany(source.DbExpressions, item, startIndex)) { joins.Add(item); } continue; case DbExpressionType.Single: case DbExpressionType.SingleOrDefault: take = 1; if (item.Expressions != null) { conditions.Add(item.Expressions[0]); } continue; case DbExpressionType.Skip: skip = (int)(item.Expressions[0] as ConstantExpression).Value; continue; case DbExpressionType.Take: take = (int)(item.Expressions[0] as ConstantExpression).Value; continue; case DbExpressionType.ThenBy: case DbExpressionType.ThenByDescending: orderBys.Add(item); continue; case DbExpressionType.Where: var predicate = group == null ? conditions : havings; if (item.Expressions != null) { predicate.Add(item.Expressions[0]); } continue; case DbExpressionType.Insert: insert = item; continue; case DbExpressionType.Update: update = item; continue; case DbExpressionType.Delete: delete = item; continue; default: throw new NotSupportedException(string.Format("{0} is not support.", item.DbExpressionType)); } #endregion } // 没有解析到INSERT/DELETE/UPDATE/SELECT表达式,并且没有相关聚合函数,则默认选择 FromEntityType 的所有字段 bool pickAllColumns = insert == null && delete == null && update == null && select == null && aggregate == null; if (pickAllColumns) { select = Expression.Constant(type ?? typeof(TElement)); } var result_Query = new DbQueryableInfo_Select <TElement>(); result_Query.FromEntityType = type; result_Query.HasDistinct = isDistinct; result_Query.HasAny = isAny; result_Query.Joins = joins; result_Query.OrderBys = orderBys; result_Query.GroupBy = group; result_Query.Aggregate = aggregate; result_Query.Unions = unions; result_Query.Includes = includes; result_Query.Skip = skip != null ? skip.Value : 0; result_Query.Take = take != null ? take.Value : 0; result_Query.Select = new DbExpression(DbExpressionType.Select, select); result_Query.Condtion = new DbExpression(DbExpressionType.Where, CombineCondition(conditions)); result_Query.Having = new DbExpression(DbExpressionType.None, CombineCondition(havings)); result_Query.SourceQuery = source; #region 更新语义 if (update != null) { var result_Update = new DbQueryableInfo_Update <TElement>(); var constantExpression = update.Expressions != null ? update.Expressions[0] as ConstantExpression : null; if (constantExpression != null) { result_Update.Entity = constantExpression.Value; } else { result_Update.Expression = update.Expressions[0]; } result_Update.SelectInfo = result_Query; result_Update.SourceQuery = source; return(result_Update); } #endregion #region 除语义 else if (delete != null) { var result_Delete = new DbQueryableInfo_Delete <TElement>(); var constantExpression = delete.Expressions != null ? delete.Expressions[0] as ConstantExpression : null; if (constantExpression != null) { result_Delete.Entity = constantExpression.Value; } result_Delete.SelectInfo = result_Query; result_Delete.SourceQuery = source; return(result_Delete); } #endregion #region 插入语义 else if (insert != null) { var result_Insert = new DbQueryableInfo_Insert <TElement>(); if (insert.Expressions != null) { result_Insert.Entity = (insert.Expressions[0] as ConstantExpression).Value; if (insert.Expressions.Length > 1) { result_Insert.EntityColumns = (insert.Expressions[1] as ConstantExpression).Value as IList <Expression>; } } result_Insert.SelectInfo = result_Query; result_Insert.Bulk = source.Bulk; result_Insert.SourceQuery = source; source.DbQueryInfo = result_Insert; return(result_Insert); } #endregion #region 择语义 else if (select != null) { // 检查嵌套查询语义 result_Query = DbQueryParser.ParseOutQuery(result_Query); // 查询来源 result_Query.SourceQuery = source; } #endregion #region 嵌套语义 // 解析嵌套查询 if (outerIndex != null) { var outQuery = DbQueryParser.Parse <TElement>(source, 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 = result_Query; } else { nQuery.SelectInfo = result_Query; } nQuery.SourceQuery = source; return(nQuery); } else if (uQuery != null) { if (uQuery.SelectInfo != null) { uQuery.SelectInfo.SubQueryInfo = result_Query; } else { uQuery.SelectInfo = result_Query; } uQuery.SourceQuery = source; return(uQuery); } else { var rootQuery = outQuery; while (rootQuery.SubQueryInfo != null) { rootQuery = rootQuery.SubQueryInfo; } rootQuery.SubQueryInfo = result_Query; outQuery.SourceQuery = source; // 如果外层是统计,内层没有分页,则不需要排序 rootQuery = outQuery; while (rootQuery.SubQueryInfo != null) { var myOutQuery = rootQuery as IDbQueryableInfo_Select; var mySubQuery = rootQuery.SubQueryInfo as IDbQueryableInfo_Select; // 没有分页的嵌套统计,不需要排序 if (myOutQuery.Aggregate != null && !(mySubQuery.Take > 0 || mySubQuery.Skip > 0) && mySubQuery.OrderBys.Count > 0) { mySubQuery.OrderBys = new List <DbExpression>(0); } // 继续下一轮迭代 rootQuery = rootQuery.SubQueryInfo; } return(outQuery); } } #endregion // 查询表达式 return(result_Query); }
/// <summary> /// 初始化 <see cref="SQLiteUpdateExpressionVisitor"/> 类的新实例 /// </summary> internal SQLiteUpdateExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, DbQueryableInfo_Update <T> uQueryInfo, string alias) : base(provider, aliases, uQueryInfo.Expression) { _alias = alias; _provider = provider; _uQueryInfo = uQueryInfo; _expression = base.Expression; }
// 解析查询语义 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); }