Ejemplo n.º 1
0
            ISqlExpression ConvertEnumerable(MethodCallExpression call)
            {
                if (call.IsAggregate(Builder.MappingSchema))
                {
                    if (call.Arguments[0].NodeType == ExpressionType.Call)
                    {
                        var arg = (MethodCallExpression)call.Arguments[0];

                        if (arg.Method.Name == "Select")
                        {
                            var arg0 = arg.Arguments[0].SkipPathThrough();

                            if (arg0.NodeType != ExpressionType.Call)
                            {
                                var l     = (LambdaExpression)arg.Arguments[1].Unwrap();
                                var largs = l.Type.GetGenericArgumentsEx();

                                if (largs.Length == 2)
                                {
                                    var p   = _element.Parent;
                                    var ctx = new ExpressionContext(Parent, _element, l);
                                    var sql = Builder.ConvertToSql(ctx, l.Body, true);

                                    Builder.ReplaceParent(ctx, p);

                                    return(new SqlFunction(call.Type, call.Method.Name, sql));
                                }
                            }
                        }
                    }
                }

                if (call.Arguments[0].NodeType == ExpressionType.Call)
                {
                    var ctx = Builder.GetSubQuery(this, call);

                    if (Builder.DataContext.SqlProviderFlags.IsSubQueryColumnSupported)
                    {
                        return(ctx.SelectQuery);
                    }

                    var join = ctx.SelectQuery.CrossApply();

                    SelectQuery.From.Tables[0].Joins.Add(join.JoinedTable);

                    return(ctx.SelectQuery.Select.Columns[0]);
                }

                var args = new ISqlExpression[call.Arguments.Count - 1];

                if (CountBuilder.MethodNames.Contains(call.Method.Name))
                {
                    if (args.Length > 0)
                    {
                        throw new InvalidOperationException();
                    }

                    return(SqlFunction.CreateCount(call.Type, SelectQuery));
                }

                var attribute =
                    Builder.MappingSchema.GetAttribute <Sql.ExpressionAttribute>(call.Method.DeclaringType, call.Method,
                                                                                 c => c.Configuration);

                if (attribute != null)
                {
                    var expr = attribute.GetExpression(Builder.DataContext, SelectQuery, call, e =>
                    {
                        var ex = e.Unwrap();

                        if (ex is LambdaExpression)
                        {
                            var l   = (LambdaExpression)ex;
                            var p   = _element.Parent;
                            var ctx = new ExpressionContext(Parent, _element, l);

                            var res = Builder.ConvertToSql(ctx, l.Body, true);

                            Builder.ReplaceParent(ctx, p);
                            return(res);
                        }
                        else
                        {
                            return(Builder.ConvertToSql(_element, ex, true));
                        }
                    });

                    if (expr != null)
                    {
                        return(expr);
                    }
                }

                if (call.Arguments.Count > 1)
                {
                    for (var i = 1; i < call.Arguments.Count; i++)
                    {
                        var ex = call.Arguments[i].Unwrap();

                        if (ex is LambdaExpression)
                        {
                            var l   = (LambdaExpression)ex;
                            var p   = _element.Parent;
                            var ctx = new ExpressionContext(Parent, _element, l);

                            args[i - 1] = Builder.ConvertToSql(ctx, l.Body, true);

                            Builder.ReplaceParent(ctx, p);
                        }
                        else
                        {
                            args[i - 1] = Builder.ConvertToSql(_element, ex, true);
                        }
                    }
                }
                else
                {
                    args = _element.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray();
                }

                if (attribute != null)
                {
                    return(attribute.GetExpression(call.Method, args));
                }

                return(new SqlFunction(call.Type, call.Method.Name, args));
            }
Ejemplo n.º 2
0
            ISqlExpression ConvertEnumerable(MethodCallExpression call)
            {
                if (AggregationBuilder.MethodNames.Contains(call.Method.Name))
                {
                    if (call.Arguments[0].NodeType == ExpressionType.Call)
                    {
                        var arg = (MethodCallExpression)call.Arguments[0];

                        if (arg.Method.Name == "Select")
                        {
                            if (arg.Arguments[0].NodeType != ExpressionType.Call)
                            {
                                var l     = (LambdaExpression)arg.Arguments[1].Unwrap();
                                var largs = l.Type.GetGenericArgumentsEx();

                                if (largs.Length == 2)
                                {
                                    var p   = _element.Parent;
                                    var ctx = new ExpressionContext(Parent, _element, l);
                                    var sql = Builder.ConvertToSql(ctx, l.Body, true);

                                    Builder.ReplaceParent(ctx, p);

                                    return(new SqlFunction(call.Type, call.Method.Name, sql));
                                }
                            }
                        }
                    }
                }

                if (call.Arguments[0].NodeType == ExpressionType.Call)
                {
                    var ctx = Builder.GetSubQuery(this, call);

                    if (Builder.DataContextInfo.SqlProviderFlags.IsSubQueryColumnSupported)
                    {
                        return(ctx.SelectQuery);
                    }

                    var join = ctx.SelectQuery.CrossApply();

                    SelectQuery.From.Tables[0].Joins.Add(join.JoinedTable);

                    return(ctx.SelectQuery.Select.Columns[0]);
                }

                var args = new ISqlExpression[call.Arguments.Count - 1];

                if (CountBuilder.MethodNames.Contains(call.Method.Name))
                {
                    if (args.Length > 0)
                    {
                        throw new InvalidOperationException();
                    }

                    return(SqlFunction.CreateCount(call.Type, SelectQuery));
                }

                if (call.Arguments.Count > 1)
                {
                    for (var i = 1; i < call.Arguments.Count; i++)
                    {
                        var ex = call.Arguments[i].Unwrap();

                        if (ex is LambdaExpression)
                        {
                            var l   = (LambdaExpression)ex;
                            var p   = _element.Parent;
                            var ctx = new ExpressionContext(Parent, _element, l);

                            args[i - 1] = Builder.ConvertToSql(ctx, l.Body, true);

                            Builder.ReplaceParent(ctx, p);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }
                else
                {
                    args = _element.ConvertToSql(null, 0, ConvertFlags.Field).Select(_ => _.Sql).ToArray();
                }

                return(new SqlFunction(call.Type, call.Method.Name, args));
            }