Exemplo n.º 1
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var returnType = methodCall.Method.ReturnType;
            var sequence   = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));

            if (sequence.SqlQuery != buildInfo.SqlQuery)
            {
                if (sequence is JoinBuilder.GroupJoinSubQueryContext)
                {
                    var ctx = new CountContext(buildInfo.Parent, sequence, returnType)
                    {
                        SqlQuery = ((JoinBuilder.GroupJoinSubQueryContext)sequence).GetCounter(methodCall)
                    };

                    ctx.Sql        = ctx.SqlQuery;
                    ctx.FieldIndex = ctx.SqlQuery.Select.Add(SqlFunction.CreateCount(returnType, ctx.SqlQuery), "cnt");

                    return(ctx);
                }

                if (sequence is GroupByBuilder.GroupByContext)
                {
                    return(new CountContext(buildInfo.Parent, sequence, returnType)
                    {
                        Sql = SqlFunction.CreateCount(returnType, sequence.SqlQuery),
                        FieldIndex = -1
                    });
                }
            }

            if (sequence.SqlQuery.Select.IsDistinct ||
                sequence.SqlQuery.Select.TakeValue != null ||
                sequence.SqlQuery.Select.SkipValue != null ||
                !sequence.SqlQuery.GroupBy.IsEmpty)
            {
                sequence.ConvertToIndex(null, 0, ConvertFlags.Key);
                sequence = new SubQueryContext(sequence);
            }

            if (sequence.SqlQuery.OrderBy.Items.Count > 0)
            {
                if (sequence.SqlQuery.Select.TakeValue == null && sequence.SqlQuery.Select.SkipValue == null)
                {
                    sequence.SqlQuery.OrderBy.Items.Clear();
                }
                else
                {
                    sequence = new SubQueryContext(sequence);
                }
            }

            var context = new CountContext(buildInfo.Parent, sequence, returnType);

            context.Sql        = context.SqlQuery;
            context.FieldIndex = context.SqlQuery.Select.Add(SqlFunction.CreateCount(returnType, context.SqlQuery), "cnt");

            return(context);
        }
Exemplo n.º 2
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence1 = new SubQueryContext(builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])));
            var sequence2 = new SubQueryContext(builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery())));
            var union     = new SqlQuery.Union(sequence2.SqlQuery, methodCall.Method.Name == "Concat");

            sequence1.SqlQuery.Unions.Add(union);

            return(new UnionContext(sequence1, sequence2, methodCall));
        }
Exemplo n.º 3
0
            protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
            {
                var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
                var extract  = (LambdaExpression)methodCall.Arguments[1].Unwrap();
                var update   = methodCall.Arguments[2].Unwrap();

                if (sequence.SqlQuery.Insert.Into == null)
                {
                    sequence.SqlQuery.Insert.Into = (SqlTable)sequence.SqlQuery.From.Tables[0].Source;
                    sequence.SqlQuery.From.Tables.Clear();
                }

                if (update.NodeType == ExpressionType.Lambda)
                {
                    UpdateBuilder.ParseSet(
                        builder,
                        buildInfo,
                        extract,
                        (LambdaExpression)update,
                        sequence,
                        sequence.SqlQuery.Insert.Into,
                        sequence.SqlQuery.Insert.Items);
                }
                else
                {
                    UpdateBuilder.ParseSet(
                        builder,
                        buildInfo,
                        extract,
                        update,
                        sequence,
                        sequence.SqlQuery.Insert.Items);
                }

                return(sequence);
            }
Exemplo n.º 4
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
            var query    = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery()));
            var except   = query.SqlQuery;

            sequence = new SubQueryContext(sequence);

            var sql = sequence.SqlQuery;

            except.ParentSql = sql;

            if (methodCall.Method.Name == "Except")
            {
                sql.Where.Not.Exists(except);
            }
            else
            {
                sql.Where.Exists(except);
            }

            var keys1 = sequence.ConvertToSql(null, 0, ConvertFlags.Key);
            var keys2 = query.ConvertToSql(null, 0, ConvertFlags.Key);

            if (keys1.Length != keys2.Length)
            {
                throw new InvalidOperationException();
            }

            for (var i = 0; i < keys1.Length; i++)
            {
                except.Where
                .Expr(keys1[i].Sql)
                .Equal
                .Expr(keys2[i].Sql);
            }

            return(sequence);
        }
Exemplo n.º 5
0
 public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 6
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));

            var isSubQuery = sequence.SqlQuery.Select.IsDistinct;

            if (isSubQuery)
            {
                sequence = new SubQueryContext(sequence);
            }

            switch (methodCall.Arguments.Count)
            {
            case 1:
                // static int Insert<T>              (this IValueInsertable<T> source)
                // static int Insert<TSource,TTarget>(this ISelectInsertable<TSource,TTarget> source)
            {
                foreach (var item in sequence.SqlQuery.Insert.Items)
                {
                    sequence.SqlQuery.Select.Expr(item.Expression);
                }
                break;
            }

            case 2:                      // static int Insert<T>(this Table<T> target, Expression<Func<T>> setter)
            {
                UpdateBuilder.BuildSetter(
                    builder,
                    buildInfo,
                    (LambdaExpression)methodCall.Arguments[1].Unwrap(),
                    sequence,
                    sequence.SqlQuery.Insert.Items,
                    sequence);

                sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)sequence).SqlTable;
                sequence.SqlQuery.From.Tables.Clear();

                break;
            }

            case 3:                      // static int Insert<TSource,TTarget>(this IQueryable<TSource> source, Table<TTarget> target, Expression<Func<TSource,TTarget>> setter)
            {
                var into = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery()));

                UpdateBuilder.BuildSetter(
                    builder,
                    buildInfo,
                    (LambdaExpression)methodCall.Arguments[2].Unwrap(),
                    into,
                    sequence.SqlQuery.Insert.Items,
                    sequence);

                sequence.SqlQuery.Select.Columns.Clear();

                foreach (var item in sequence.SqlQuery.Insert.Items)
                {
                    sequence.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence.SqlQuery, item.Expression));
                }

                sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)into).SqlTable;

                break;
            }
            }

            var insert = sequence.SqlQuery.Insert;

            var q = insert.Into.Fields.Values.Cast <ISqlExpression>().Except(insert.Items.Select(e => e.Column))
                    .OfType <SqlField>()
                    .Where(f => f.IsIdentity);

            foreach (var field in q)
            {
                var expr = builder.SqlProvider.GetIdentityExpression(insert.Into, field, false);

                if (expr != null)
                {
                    insert.Items.Insert(0, new SqlQuery.SetExpression(field, expr));

                    if (methodCall.Arguments.Count == 3)
                    {
                        sequence.SqlQuery.Select.Columns.Insert(0, new SqlQuery.Column(sequence.SqlQuery, insert.Items[0].Expression));
                    }
                }
            }

            sequence.SqlQuery.QueryType           = QueryType.Insert;
            sequence.SqlQuery.Insert.WithIdentity = methodCall.Method.Name == "InsertWithIdentity";

            return(new InsertContext(buildInfo.Parent, sequence, sequence.SqlQuery.Insert.WithIdentity));
        }
Exemplo n.º 7
0
            public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
            {
                if (expression == null && buildInfo != null)
                {
                    if (buildInfo.Parent is SelectManyBuilder.SelectManyContext)
                    {
                        var sm     = (SelectManyBuilder.SelectManyContext)buildInfo.Parent;
                        var ctype  = typeof(ContextHelper <>).MakeGenericType(_key.Lambda.Parameters[0].Type);
                        var helper = (IContextHelper)Activator.CreateInstance(ctype);
                        var expr   = helper.GetContext(
                            Sequence.Expression,
                            _key.Lambda.Parameters[0],
                            Expression.PropertyOrField(sm.Lambda.Parameters[0], "Key"),
                            _key.Lambda.Body);

                        return(Builder.BuildSequence(new BuildInfo(buildInfo, expr)));
                    }

                    //if (buildInfo.Parent == this)
                    {
                        var ctype  = typeof(ContextHelper <>).MakeGenericType(_key.Lambda.Parameters[0].Type);
                        var helper = (IContextHelper)Activator.CreateInstance(ctype);
                        var expr   = helper.GetContext(
                            _sequenceExpr,
                            _key.Lambda.Parameters[0],
                            Expression.PropertyOrField(buildInfo.Expression, "Key"),
                            _key.Lambda.Body);

                        var ctx = Builder.BuildSequence(new BuildInfo(buildInfo, expr));

                        ctx.SqlQuery.Properties.Add(Tuple.Create("from_group_by", SqlQuery));

                        return(ctx);
                    }

                    //return this;
                }

                if (level != 0)
                {
                    var levelExpression = expression.GetLevelExpression(level);

                    if (levelExpression.NodeType == ExpressionType.MemberAccess)
                    {
                        var ma = (MemberExpression)levelExpression;

                        if (ma.Member.Name == "Key" && ma.Member.DeclaringType == _groupingType)
                        {
                            return(levelExpression == expression?
                                   _key.GetContext(null, 0, buildInfo) :
                                       _key.GetContext(expression, level + 1, buildInfo));
                        }
                    }
                }

                throw new NotImplementedException();
            }
Exemplo n.º 8
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));

            if (methodCall.Arguments.Count == 2)
            {
                sequence = builder.BuildWhere(buildInfo.Parent, sequence, (LambdaExpression)methodCall.Arguments[1].Unwrap(), false);
            }

            sequence.SqlQuery.QueryType = QueryType.Delete;

            return(new DeleteContext(buildInfo.Parent, sequence));
        }
Exemplo n.º 9
0
        protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            if (!methodCall.IsQueryable("GroupBy"))
            {
                return(false);
            }

            var body = ((LambdaExpression)methodCall.Arguments[1].Unwrap()).Body.Unwrap();

            if (body.NodeType == ExpressionType.MemberInit)
            {
                var  mi = (MemberInitExpression)body;
                bool throwExpr;

                if (mi.NewExpression.Arguments.Count > 0 || mi.Bindings.Count == 0)
                {
                    throwExpr = true;
                }
                else
                {
                    throwExpr = mi.Bindings.Any(b => b.BindingType != MemberBindingType.Assignment);
                }

                if (throwExpr)
                {
                    throw new NotSupportedException(string.Format("Explicit construction of entity type '{0}' in group by is not allowed.", body.Type));
                }
            }

            return(methodCall.Arguments[methodCall.Arguments.Count - 1].Unwrap().NodeType == ExpressionType.Lambda);
        }
Exemplo n.º 10
0
        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.GetGenericArguments()[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.IsGenericType && 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 (groupSql.Any(_ => !(_.Sql is SqlField || _.Sql is SqlQuery.Column)))
            {
                sequence = new SubQueryContext(sequence);
                key      = new KeyContext(buildInfo.Parent, keySelector, sequence);
                groupSql = builder.ConvertExpressions(key, keySelector.Body.Unwrap(), ConvertFlags.Key);
            }

            sequence.SqlQuery.GroupBy.Items.Clear();

            foreach (var sql in groupSql)
            {
                sequence.SqlQuery.GroupBy.Expr(sql.Sql);
            }

            new QueryVisitor().Visit(sequence.SqlQuery.From, e =>
            {
                if (e.ElementType == QueryElementType.JoinedTable)
                {
                    var jt = (SqlQuery.JoinedTable)e;
                    if (jt.JoinType == SqlQuery.JoinType.Inner)
                    {
                        jt.IsWeak = false;
                    }
                }
            });

            var element = new SelectContext(buildInfo.Parent, elementSelector, sequence /*, key*/);
            var groupBy = new GroupByContext(buildInfo.Parent, sequenceExpr, groupingType, sequence, key, element);

            return(groupBy);
        }
Exemplo n.º 11
0
            public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
            {
                if (Collection != null)
                {
                    if (expression == null)
                    {
                        return(Collection.GetContext(expression, level, buildInfo));
                    }

                    var root = expression.GetRootObject();

                    if (root != Lambda.Parameters[0])
                    {
                        return(Collection.GetContext(expression, level, buildInfo));
                    }
                }

                return(base.GetContext(expression, level, buildInfo));
            }
Exemplo n.º 12
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence           = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
            var collectionSelector = (LambdaExpression)methodCall.Arguments[1].Unwrap();
            var resultSelector     = (LambdaExpression)methodCall.Arguments[2].Unwrap();

            if (!sequence.SqlQuery.GroupBy.IsEmpty)
            {
                sequence = new SubQueryContext(sequence);
            }

            var context = new SelectManyContext(buildInfo.Parent, collectionSelector, sequence);
            var expr    = collectionSelector.Body.Unwrap();

            var collectionInfo = new BuildInfo(context, expr, new SqlQuery());
            var collection     = builder.BuildSequence(collectionInfo);
            var leftJoin       = collection is DefaultIfEmptyBuilder.DefaultIfEmptyContext;
            var sql            = collection.SqlQuery;

            var sequenceTable = sequence.SqlQuery.From.Tables[0].Source;
            var newQuery      = null != new QueryVisitor().Find(sql, e => e == collectionInfo.SqlQuery);
            var crossApply    = null != new QueryVisitor().Find(sql, e =>
                                                                e == sequenceTable ||
                                                                e.ElementType == QueryElementType.SqlField && sequenceTable == ((SqlField)e).Table ||
                                                                e.ElementType == QueryElementType.Column && sequenceTable == ((SqlQuery.Column)e).Parent);

            if (collection is JoinBuilder.GroupJoinSubQueryContext)
            {
                var groupJoin = ((JoinBuilder.GroupJoinSubQueryContext)collection).GroupJoin;

                groupJoin.SqlQuery.From.Tables[0].Joins[0].JoinType = SqlQuery.JoinType.Inner;
                groupJoin.SqlQuery.From.Tables[0].Joins[0].IsWeak   = false;
            }

            if (!newQuery)
            {
                context.Collection = new SubQueryContext(collection, sequence.SqlQuery, false);
                return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context));
            }

            if (!crossApply)
            {
                if (!leftJoin)
                {
                    context.Collection = new SubQueryContext(collection, sequence.SqlQuery, true);
                    return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context));
                }
                else
                {
                    var join = SqlQuery.OuterApply(sql);
                    sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable);
                    context.Collection = new SubQueryContext(collection, sequence.SqlQuery, false);

                    return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context));
                }
            }

            if (collection is TableBuilder.TableContext)
            {
                var table = (TableBuilder.TableContext)collection;

                var join = table.SqlTable.TableArguments != null && table.SqlTable.TableArguments.Length > 0 ?
                           leftJoin ? SqlQuery.OuterApply(sql) : SqlQuery.CrossApply(sql) :
                           leftJoin?SqlQuery.LeftJoin(sql) : SqlQuery.InnerJoin(sql);

                join.JoinedTable.Condition.Conditions.AddRange(sql.Where.SearchCondition.Conditions);

                sql.Where.SearchCondition.Conditions.Clear();

                var collectionParent = collection.Parent as TableBuilder.TableContext;

                // Association.
                //
                if (collectionParent != null && collectionInfo.IsAssociationBuilt)
                {
                    var ts = (SqlQuery.TableSource) new QueryVisitor().Find(sequence.SqlQuery.From, e =>
                    {
                        if (e.ElementType == QueryElementType.TableSource)
                        {
                            var t = (SqlQuery.TableSource)e;
                            return(t.Source == collectionParent.SqlTable);
                        }

                        return(false);
                    });

                    ts.Joins.Add(join.JoinedTable);
                }
                else
                {
                    sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable);
                }

                context.Collection = new SubQueryContext(collection, sequence.SqlQuery, false);
                return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context));
            }
            else
            {
                var join = leftJoin ? SqlQuery.OuterApply(sql) : SqlQuery.CrossApply(sql);
                sequence.SqlQuery.From.Tables[0].Joins.Add(join.JoinedTable);

                context.Collection = new SubQueryContext(collection, sequence.SqlQuery, false);
                return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context));
            }
        }
Exemplo n.º 13
0
 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
 {
     return
         (methodCall.IsQueryable("SelectMany") &&
          methodCall.Arguments.Count == 3 &&
          ((LambdaExpression)methodCall.Arguments[1].Unwrap()).Parameters.Count == 1);
 }
Exemplo n.º 14
0
        public virtual IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
        {
            if (expression == null)
            {
                return(this);
            }

            if (IsScalar)
            {
                return(ProcessScalar(
                           expression,
                           level,
                           (ctx, ex, l) => ctx.GetContext(ex, l, buildInfo),
                           () => { throw new InvalidOperationException(); }));
            }
            else
            {
                var levelExpression = expression.GetLevelExpression(level);

                switch (levelExpression.NodeType)
                {
                case ExpressionType.MemberAccess:
                {
                    if (levelExpression == expression && Sequence.Length == 1 && !(Sequence[0] is GroupByBuilder.GroupByContext))
                    {
                        var memberExpression = GetMemberExpression(
                            ((MemberExpression)levelExpression).Member,
                            levelExpression == expression,
                            levelExpression.Type);

                        //var sequence = GetSequence(memberExpression, 0);
                        //return sequence.GetContext(memberExpression, 1, new BuildInfo(buildInfo, memberExpression));

                        var ctx = GetContext(memberExpression, 0, new BuildInfo(this, memberExpression, buildInfo.SqlQuery));

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

                    var context = ProcessMemberAccess(
                        expression,
                        (MemberExpression)levelExpression,
                        level,
                        (n, ctx, ex, l, _) => n == 0 ?
                        null :
                        ctx.GetContext(ex, l, buildInfo));

                    if (context == null)
                    {
                        throw new InvalidOperationException();
                    }

                    return(context);
                }

                case ExpressionType.Parameter:
                {
                    var sequence  = GetSequence(expression, level);
                    var parameter = Lambda.Parameters[Sequence.Length == 0 ? 0 : Array.IndexOf(Sequence, sequence)];

                    if (levelExpression == expression)
                    {
                        if (levelExpression == parameter)
                        {
                            return(sequence.GetContext(null, 0, buildInfo));
                        }
                    }
                    else if (level == 0)
                    {
                        return(sequence.GetContext(expression, 1, buildInfo));
                    }

                    break;
                }
                }

                if (level == 0)
                {
                    var sequence = GetSequence(expression, level);
                    return(sequence.GetContext(expression, level + 1, buildInfo));
                }
            }

            throw new InvalidOperationException();
        }
Exemplo n.º 15
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));

            switch (methodCall.Arguments.Count)
            {
            case 1:                      // int Update<T>(this IUpdateable<T> source)
                break;

            case 2:                      // int Update<T>(this IQueryable<T> source, Expression<Func<T,T>> setter)
            {
                BuildSetter(
                    builder,
                    buildInfo,
                    (LambdaExpression)methodCall.Arguments[1].Unwrap(),
                    sequence,
                    sequence.SqlQuery.Update.Items,
                    sequence);
                break;
            }

            case 3:
            {
                var expr = methodCall.Arguments[1].Unwrap();

                if (expr is LambdaExpression)
                {
                    // int Update<T>(this IQueryable<T> source, Expression<Func<T,bool>> predicate, Expression<Func<T,T>> setter)
                    //
                    sequence = builder.BuildWhere(buildInfo.Parent, sequence, (LambdaExpression)methodCall.Arguments[1].Unwrap(), false);

                    BuildSetter(
                        builder,
                        buildInfo,
                        (LambdaExpression)methodCall.Arguments[2].Unwrap(),
                        sequence,
                        sequence.SqlQuery.Update.Items,
                        sequence);
                }
                else
                {
                    // static int Update<TSource,TTarget>(this IQueryable<TSource> source, Table<TTarget> target, Expression<Func<TSource,TTarget>> setter)
                    //
                    var into = builder.BuildSequence(new BuildInfo(buildInfo, expr, new SqlQuery()));

                    BuildSetter(
                        builder,
                        buildInfo,
                        (LambdaExpression)methodCall.Arguments[2].Unwrap(),
                        into,
                        sequence.SqlQuery.Update.Items,
                        sequence);

                    var sql = sequence.SqlQuery;

                    sql.Select.Columns.Clear();

                    foreach (var item in sql.Update.Items)
                    {
                        sql.Select.Columns.Add(new SqlQuery.Column(sql, item.Expression));
                    }

                    sql.Update.Table = ((TableBuilder.TableContext)into).SqlTable;
                }

                break;
            }
            }

            sequence.SqlQuery.QueryType = QueryType.Update;

            return(new UpdateContext(buildInfo.Parent, sequence));
        }
Exemplo n.º 16
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));

            var isSubQuery = sequence.SqlQuery.Select.IsDistinct;

            if (isSubQuery)
            {
                sequence = new SubQueryContext(sequence);
            }

            switch (methodCall.Arguments.Count)
            {
            case 1:
                // static int Insert<T>              (this IValueInsertable<T> source)
                // static int Insert<TSource,TTarget>(this ISelectInsertable<TSource,TTarget> source)
            {
                foreach (var item in sequence.SqlQuery.Insert.Items)
                {
                    sequence.SqlQuery.Select.Expr(item.Expression);
                }
                break;
            }

            case 2:                      // static int Insert<T>(this Table<T> target, Expression<Func<T>> setter)
            {
                UpdateBuilder.BuildSetter(
                    builder,
                    buildInfo,
                    (LambdaExpression)methodCall.Arguments[1].Unwrap(),
                    sequence,
                    sequence.SqlQuery.Insert.Items,
                    sequence);

                sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)sequence).SqlTable;
                sequence.SqlQuery.From.Tables.Clear();

                break;
            }

            case 3:                      // static int Insert<TSource,TTarget>(this IQueryable<TSource> source, Table<TTarget> target, Expression<Func<TSource,TTarget>> setter)
            {
                var into = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1], new SqlQuery()));

                UpdateBuilder.BuildSetter(
                    builder,
                    buildInfo,
                    (LambdaExpression)methodCall.Arguments[2].Unwrap(),
                    into,
                    sequence.SqlQuery.Insert.Items,
                    sequence);

                sequence.SqlQuery.Select.Columns.Clear();

                foreach (var item in sequence.SqlQuery.Insert.Items)
                {
                    sequence.SqlQuery.Select.Columns.Add(new SqlQuery.Column(sequence.SqlQuery, item.Expression));
                }

                sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)into).SqlTable;

                break;
            }
            }

            sequence.SqlQuery.QueryType           = QueryType.Insert;
            sequence.SqlQuery.Insert.WithIdentity = methodCall.Method.Name == "InsertWithIdentity";

            return(new InsertContext(buildInfo.Parent, sequence, sequence.SqlQuery.Insert.WithIdentity));
        }
Exemplo n.º 17
0
        internal static void ParseSet(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression extract,
            LambdaExpression update,
            IBuildContext select,
            SqlTable table,
            List <SqlQuery.SetExpression> items)
        {
            var ext = extract.Body;

            while (ext.NodeType == ExpressionType.Convert || ext.NodeType == ExpressionType.ConvertChecked)
            {
                ext = ((UnaryExpression)ext).Operand;
            }

            if (ext.NodeType != ExpressionType.MemberAccess || ext.GetRootObject() != extract.Parameters[0])
            {
                throw new LinqException("Member expression expected for the 'Set' statement.");
            }

            var body   = (MemberExpression)ext;
            var member = body.Member;

            if (member is MethodInfo)
            {
                member = TypeHelper.GetPropertyByMethod((MethodInfo)member);
            }

            var members = body.GetMembers();
            var name    = members
                          .Skip(1)
                          .Select(ex =>
            {
                var me = ex as MemberExpression;

                if (me == null)
                {
                    return(null);
                }

                var m = me.Member;

                if (m is MethodInfo)
                {
                    m = TypeHelper.GetPropertyByMethod((MethodInfo)m);
                }

                return(m);
            })
                          .Where(m => m != null && !TypeHelper.IsNullableValueMember(m))
                          .Select(m => m.Name)
                          .Aggregate((s1, s2) => s1 + "." + s2);

            if (table != null && !table.Fields.ContainsKey(name))
            {
                throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, name);
            }

            var column = table != null ?
                         table.Fields[name] :
                         select.ConvertToSql(
                body, 1, ConvertFlags.Field)[0].Sql;
            //Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field)[0].Sql;
            var sp   = select.Parent;
            var ctx  = new ExpressionContext(buildInfo.Parent, select, update);
            var expr = builder.ConvertToSqlExpression(ctx, update.Body);

            builder.ReplaceParent(ctx, sp);

            if (expr is SqlParameter && update.Body.Type.IsEnum)
            {
                ((SqlParameter)expr).SetEnumConverter(update.Body.Type, builder.MappingSchema);
            }

            items.Add(new SqlQuery.SetExpression(column, expr));
        }
Exemplo n.º 18
0
 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
 {
     return(methodCall.IsQueryable("Insert", "InsertWithIdentity"));
 }
Exemplo n.º 19
0
            protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
            {
                var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
                var extract  = (LambdaExpression)methodCall.Arguments[1].Unwrap();
                var update   = methodCall.Arguments[2].Unwrap();

                if (update.NodeType == ExpressionType.Lambda)
                {
                    ParseSet(
                        builder,
                        buildInfo,
                        extract,
                        (LambdaExpression)update,
                        sequence,
                        sequence.SqlQuery.Update.Table,
                        sequence.SqlQuery.Update.Items);
                }
                else
                {
                    ParseSet(
                        builder,
                        buildInfo,
                        extract,
                        update,
                        sequence,
                        sequence.SqlQuery.Update.Items);
                }

                return(sequence);
            }
Exemplo n.º 20
0
            protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
            {
                var source = methodCall.Arguments[0].Unwrap();
                var into   = methodCall.Arguments[1].Unwrap();

                IBuildContext sequence;

                // static IValueInsertable<T> Into<T>(this IDataContext dataContext, Table<T> target)
                //
                if (source.NodeType == ExpressionType.Constant && ((ConstantExpression)source).Value == null)
                {
                    sequence = builder.BuildSequence(new BuildInfo((IBuildContext)null, into, new SqlQuery()));
                    sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)sequence).SqlTable;
                    sequence.SqlQuery.From.Tables.Clear();
                }
                // static ISelectInsertable<TSource,TTarget> Into<TSource,TTarget>(this IQueryable<TSource> source, Table<TTarget> target)
                //
                else
                {
                    sequence = builder.BuildSequence(new BuildInfo(buildInfo, source));
                    var tbl = builder.BuildSequence(new BuildInfo((IBuildContext)null, into, new SqlQuery()));
                    sequence.SqlQuery.Insert.Into = ((TableBuilder.TableContext)tbl).SqlTable;
                }

                sequence.SqlQuery.Select.Columns.Clear();

                return(sequence);
            }
Exemplo n.º 21
0
 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
 {
     return
         (methodCall.IsQueryable(MethodNames) &&
          methodCall.Arguments.Count == 1);
 }
Exemplo n.º 22
0
 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
 {
     return(methodCall.IsQueryable("Value"));
 }
Exemplo n.º 23
0
 public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
 {
     throw new InvalidOperationException();
 }
Exemplo n.º 24
0
 protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
 {
     return(methodCall.Arguments.Count == 2 && methodCall.IsQueryable("Except", "Intersect"));
 }
Exemplo n.º 25
0
        protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo)
        {
            var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0]));
            var take     = 0;

            if (!buildInfo.IsSubQuery || builder.SqlProvider.IsSubQueryTakeSupported)
            {
                switch (methodCall.Method.Name)
                {
                case "First":
                case "FirstOrDefault":
                    take = 1;
                    break;

                case "Single":
                case "SingleOrDefault":
                    if (!buildInfo.IsSubQuery)
                    {
                        take = 2;
                    }
                    break;
                }
            }

            if (take != 0)
            {
                builder.BuildTake(sequence, new SqlValue(take));
            }

            return(new FirstSingleContext(buildInfo.Parent, sequence, methodCall));
        }
Exemplo n.º 26
0
 protected override SequenceConvertInfo Convert(
     ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param)
 {
     return(null);
 }
Exemplo n.º 27
0
 public override IBuildContext GetContext(Expression expression, int level, BuildInfo buildInfo)
 {
     return(Sequence.GetContext(expression, level, buildInfo));
 }