protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequenceExpr = methodCall.Arguments[0]; var sequence = builder.BuildSequence(new BuildInfo(buildInfo, sequenceExpr)); var groupingType = methodCall.Type.GetGenericArgumentsEx()[0]; var keySelector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var elementSelector = (LambdaExpression)methodCall.Arguments[2].Unwrap(); if (methodCall.Arguments[0].NodeType == ExpressionType.Call) { var call = (MethodCallExpression)methodCall.Arguments[0]; if (call.Method.Name == "Select") { var type = ((LambdaExpression)call.Arguments[1].Unwrap()).Body.Type; if (type.IsGenericTypeEx() && type.GetGenericTypeDefinition() == typeof(ExpressionBuilder.GroupSubQuery <,>)) { sequence = new SubQueryContext(sequence); } } } var key = new KeyContext(buildInfo.Parent, keySelector, sequence); var groupSql = builder.ConvertExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key); if (sequence.Select.Select.IsDistinct || sequence.Select.GroupBy.Items.Count > 0 || groupSql.Any(_ => !(_.Sql is ISqlField || _.Sql is IColumn))) { sequence = new SubQueryContext(sequence); key = new KeyContext(buildInfo.Parent, keySelector, sequence); groupSql = builder.ConvertExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key); } foreach (var sql in groupSql) { sequence.Select.GroupBy.Expr(sql.Sql); } foreach ( var join in QueryVisitor.FindOnce <IJoinedTable>(sequence.Select.From).Where(f => f.JoinType == EJoinType.Inner)) { join.IsWeak = false; } var element = new SelectContext(buildInfo.Parent, elementSelector, sequence /*, key*/); var groupBy = new GroupByContext(buildInfo.Parent, sequenceExpr, groupingType, sequence, key, element); return(groupBy); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); if (sequence.Select.Select.TakeValue != null || sequence.Select.Select.SkipValue != null || sequence.Select.Select.IsDistinct && !builder.DataContextInfo.SqlProviderFlags.IsDistinctOrderBySupported) { sequence = new SubQueryContext(sequence); } var lambda = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var sparent = sequence.Parent; var order = new ExpressionContext(buildInfo.Parent, sequence, lambda); var body = lambda.Body.Unwrap(); var sql = builder.ConvertExpressions(order, body, ConvertFlags.Key); builder.ReplaceParent(order, sparent); if (!methodCall.Method.Name.StartsWith("Then")) { sequence.Select.OrderBy.Items.Clear(); } foreach (var expr in sql) { var e = builder.ConvertSearchCondition(sequence, expr.Sql); sequence.Select.OrderBy.Expr(e, methodCall.Method.Name.EndsWith("Descending")); } return(sequence); }