GroupByBuilder.GroupByContext?GetGroupByContext(ExpressionBuilder builder, BuildInfo buildInfo) { if (buildInfo.Expression.NodeType == ExpressionType.Parameter) { if (typeof(IGrouping <,>).IsSameOrParentOf(buildInfo.Expression.Type)) { var context = builder.GetContext(buildInfo.Parent, buildInfo.Expression); if (context is SelectContext sc) { var current = sc.Sequence[0]; while (current is SubQueryContext subQuery) { current = subQuery.SubQuery; } if (current is GroupByBuilder.GroupByContext groupByContext) { return(groupByContext); } } } } return(null); }
static T Find <T>(ExpressionBuilder builder, BuildInfo buildInfo, Func <int, IBuildContext, T> action) { var expression = buildInfo.Expression; switch (expression.NodeType) { case ExpressionType.Constant: { var c = (ConstantExpression)expression; if (c.Value is IQueryable) { return(action(1, null)); } break; } case ExpressionType.Call: { var mc = (MethodCallExpression)expression; if (mc.Method.Name == "GetTable") { if (typeof(ITable <>).IsSameOrParentOf(expression.Type)) { return(action(2, null)); } } var attr = builder.GetTableFunctionAttribute(mc.Method); if (attr != null) { return(action(5, null)); } break; } case ExpressionType.MemberAccess: if (typeof(ITable <>).IsSameOrParentOf(expression.Type)) { return(action(3, null)); } // Looking for association. // if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0) { var ctx = builder.GetContext(buildInfo.Parent, expression); if (ctx != null) { return(action(4, ctx)); } } break; case ExpressionType.Parameter: { if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0) { var ctx = builder.GetContext(buildInfo.Parent, expression); if (ctx != null) { return(action(4, ctx)); } } break; } } return(action(0, null)); }
static BuildContextType FindBuildContext(ExpressionBuilder builder, BuildInfo buildInfo, out IBuildContext?parentContext) { parentContext = null; var expression = buildInfo.Expression; switch (expression.NodeType) { case ExpressionType.Constant: { var c = (ConstantExpression)expression; if (c.Value is IQueryable queryable) { if (typeof(CteTable <>).IsSameOrParentOf(c.Value.GetType())) { return(BuildContextType.CteConstant); } // Avoid collision with ArrayBuilder var elementType = queryable.ElementType; if (builder.MappingSchema.IsScalarType(elementType) && typeof(EnumerableQuery <>).IsSameOrParentOf(c.Value.GetType())) { break; } if (queryable.Expression.NodeType == ExpressionType.NewArrayInit) { break; } return(BuildContextType.TableConstant); } break; } case ExpressionType.Call: { var mc = (MethodCallExpression)expression; switch (mc.Method.Name) { case "GetTable": { if (typeof(ITable <>).IsSameOrParentOf(expression.Type)) { return(BuildContextType.GetTableMethod); } break; } case "AsCte": return(BuildContextType.AsCteMethod); case "FromSql": return(BuildContextType.FromSqlMethod); case "FromSqlScalar": return(BuildContextType.FromSqlScalarMethod); } var attr = mc.Method.GetTableFunctionAttribute(builder.MappingSchema); if (attr != null) { return(BuildContextType.TableFunctionAttribute); } if (mc.IsAssociation(builder.MappingSchema)) { parentContext = builder.GetContext(buildInfo.Parent, expression); if (parentContext != null) { return(BuildContextType.Association); } } break; } case ExpressionType.MemberAccess: if (typeof(ITable <>).IsSameOrParentOf(expression.Type)) { return(BuildContextType.MemberAccess); } // Looking for association. // if (buildInfo.IsSubQuery /* && buildInfo.SelectQuery.From.Tables.Count == 0*/) { parentContext = builder.GetContext(buildInfo.Parent, expression); if (parentContext != null) { return(BuildContextType.Association); } } break; case ExpressionType.Parameter: { if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0) { // It should be handled by GroupByElementBuilder // if (typeof(IGrouping <,>).IsSameOrParentOf(expression.Type)) { break; } parentContext = builder.GetContext(buildInfo.Parent, expression); if (parentContext != null) { return(BuildContextType.Association); } } break; } } return(BuildContextType.None); }
static BuildContextType FindBuildContext(ExpressionBuilder builder, BuildInfo buildInfo, out IBuildContext parentContext) { parentContext = null; var expression = buildInfo.Expression; switch (expression.NodeType) { case ExpressionType.Constant: { var c = (ConstantExpression)expression; if (c.Value is IQueryable) { if (typeof(CteTable <>).IsSameOrParentOf(c.Value.GetType())) { return(BuildContextType.CteConstant); } return(BuildContextType.TableConstant); } break; } case ExpressionType.Call: { var mc = (MethodCallExpression)expression; switch (mc.Method.Name) { case "GetTable": if (typeof(ITable <>).IsSameOrParentOf(expression.Type)) { return(BuildContextType.GetTableMethod); } break; case "AsCte": return(BuildContextType.AsCteMethod); } var attr = builder.GetTableFunctionAttribute(mc.Method); if (attr != null) { return(BuildContextType.TableFunctionAttribute); } if (mc.IsAssociation(builder.MappingSchema)) { parentContext = builder.GetContext(buildInfo.Parent, expression); if (parentContext != null) { return(BuildContextType.Association); } } break; } case ExpressionType.MemberAccess: if (typeof(ITable <>).IsSameOrParentOf(expression.Type)) { return(BuildContextType.MemberAccess); } // Looking for association. // if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0) { parentContext = builder.GetContext(buildInfo.Parent, expression); if (parentContext != null) { return(BuildContextType.Association); } } break; case ExpressionType.Parameter: { if (buildInfo.IsSubQuery && buildInfo.SelectQuery.From.Tables.Count == 0) { parentContext = builder.GetContext(buildInfo.Parent, expression); if (parentContext != null) { return(BuildContextType.Association); } } break; } } return(BuildContextType.None); }