public override SqlInfo[] ConvertToSql(Expression expression, int level, ConvertFlags flags)
            {
                if (_innerContext != null)
                {
                    return(_innerContext.ConvertToSql(expression, level, flags));
                }

                return(base.ConvertToSql(expression, level, flags));
            }
示例#2
0
            public override SqlInfo[] ConvertToSql(Expression?expression, int level, ConvertFlags flags)
            {
                if (expression != null)
                {
                    switch (flags)
                    {
                    case ConvertFlags.Field:
                    {
                        var root = Builder.GetRootObject(expression);

                        if (root.NodeType == ExpressionType.Parameter)
                        {
                            if (_sourceParameters.Contains(root))
                            {
                                return(_source.ConvertToSql(expression, level, flags));
                            }

                            return(_target !.ConvertToSql(expression, level, flags));
                        }

                        if (root is ContextRefExpression contextRef)
                        {
                            return(contextRef.BuildContext.ConvertToSql(expression, level, flags));
                        }

                        break;
                    }
                    }
                }

                throw new LinqException("'{0}' cannot be converted to SQL.", expression);
            }
示例#3
0
        internal static void BuildSetter(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression setter,
            IBuildContext into,
            List <SqlQuery.SetExpression> items,
            IBuildContext sequence)
        {
            var path = Expression.Parameter(setter.Body.Type, "p");
            var ctx  = new ExpressionContext(buildInfo.Parent, sequence, setter);

            if (setter.Body.NodeType == ExpressionType.MemberInit)
            {
                var ex = (MemberInitExpression)setter.Body;
                var p  = sequence.Parent;

                BuildSetter(builder, into, items, ctx, ex, path);

                builder.ReplaceParent(ctx, p);
            }
            else
            {
                var sqlInfo = ctx.ConvertToSql(setter.Body, 0, ConvertFlags.All);

                foreach (var info in sqlInfo)
                {
                    if (info.Members.Count == 0)
                    {
                        throw new LinqException("Object initializer expected for insert statement.");
                    }

                    if (info.Members.Count != 1)
                    {
                        throw new InvalidOperationException();
                    }

                    var member = info.Members[0];
                    var pe     = Expression.MakeMemberAccess(path, member);
                    var column = into.ConvertToSql(pe, 1, ConvertFlags.Field);
                    var expr   = info.Sql;

                    if (expr is SqlParameter)
                    {
                        SetConverter(builder.MappingSchema, member, expr);
                        //var type = member.MemberType == MemberTypes.Field ?
                        //	((FieldInfo)   member).FieldType :
                        //	((PropertyInfo)member).PropertyType;

                        //if (TypeHelper.IsEnumOrNullableEnum(type))
                        //{
                        //	var memberAccessor = TypeAccessor.GetAccessor(member.DeclaringType)[member.Name];
                        //	((SqlParameter)expr).SetEnumConverter(memberAccessor, builder.MappingSchema);
                        //}
                    }

                    items.Add(new SqlQuery.SetExpression(column[0].Sql, expr));
                }
            }
        }
示例#4
0
        static void BuildSetter(
            ExpressionBuilder builder,
            IBuildContext into,
            List <SelectQuery.SetExpression> items,
            IBuildContext ctx,
            MemberInitExpression expression,
            Expression path)
        {
            foreach (var binding in expression.Bindings)
            {
                var member = binding.Member;

                if (member is MethodInfo)
                {
                    member = ((MethodInfo)member).GetPropertyInfo();
                }

                if (binding is MemberAssignment)
                {
                    var ma = binding as MemberAssignment;
                    var pe = Expression.MakeMemberAccess(path, member);

                    if (ma.Expression is MemberInitExpression && !into.IsExpression(pe, 1, RequestFor.Field).Result)
                    {
                        BuildSetter(
                            builder,
                            into,
                            items,
                            ctx,
                            (MemberInitExpression)ma.Expression, Expression.MakeMemberAccess(path, member));
                    }
                    else
                    {
                        var column = into.ConvertToSql(pe, 1, ConvertFlags.Field);
                        var expr   = builder.ConvertToSqlExpression(ctx, ma.Expression);

                        if (expr.ElementType == QueryElementType.SqlParameter)
                        {
                            var parm  = (SqlParameter)expr;
                            var field = column[0].Sql is SqlField
                                                                ? (SqlField)column[0].Sql
                                                                : (SqlField)((SelectQuery.Column)column[0].Sql).Expression;

                            if (parm.DataType == DataType.Undefined)
                            {
                                parm.DataType = field.DataType;
                            }
                        }

                        items.Add(new SelectQuery.SetExpression(column[0].Sql, expr));
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
示例#5
0
        internal static void ParseSet(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression extract,
            Expression update,
            IBuildContext select,
            List <SqlQuery.SetExpression> items)
        {
            var ext = extract.Body;

            if (!ExpressionHelper.IsConstant(update.Type) && !builder.AsParameters.Contains(update))
            {
                builder.AsParameters.Add(update);
            }

            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 column = select.ConvertToSql(
                body, 1, ConvertFlags.Field);

            //Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field);

            if (column.Length == 0)
            {
                throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, member.Name);
            }

            var expr = builder.ConvertToSql(select, update, false, false);

            if (expr is SqlValueBase && TypeHelper.IsEnumOrNullableEnum(update.Type))
            {
                var memberAccessor = TypeAccessor.GetAccessor(body.Member.DeclaringType)[body.Member.Name];
                ((SqlValueBase)expr).SetEnumConverter(memberAccessor, builder.MappingSchema);
            }

            items.Add(new SqlQuery.SetExpression(column[0].Sql, expr));
        }
示例#6
0
        static void BuildSetter(
            ExpressionBuilder builder,
            IBuildContext into,
            List <SqlQuery.SetExpression> items,
            IBuildContext ctx,
            MemberInitExpression expression,
            Expression path)
        {
            foreach (var binding in expression.Bindings)
            {
                var member = binding.Member;

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

                if (binding is MemberAssignment)
                {
                    var ma = binding as MemberAssignment;
                    var pe = Expression.MakeMemberAccess(path, member);

                    if (ma.Expression is MemberInitExpression && !into.IsExpression(pe, 1, RequestFor.Field).Result)
                    {
                        BuildSetter(
                            builder,
                            into,
                            items,
                            ctx,
                            (MemberInitExpression)ma.Expression, Expression.MakeMemberAccess(path, member));
                    }
                    else
                    {
                        var column = into.ConvertToSql(pe, 1, ConvertFlags.Field);
                        var expr   = builder.ConvertToSqlExpression(ctx, ma.Expression, false);

                        if (expr is SqlValueBase && TypeHelper.IsEnumOrNullableEnum(ma.Expression.Type))
                        {
                            var memberAccessor = TypeAccessor.GetAccessor(ma.Member.DeclaringType)[ma.Member.Name];
                            ((SqlValueBase)expr).SetEnumConverter(memberAccessor, builder.MappingSchema);
                        }

                        items.Add(new SqlQuery.SetExpression(column[0].Sql, expr));
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
示例#7
0
        internal static void ParseSet(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression extract,
            Expression update,
            IBuildContext select)
        {
            var pi = extract.Body;

            if (!ExpressionHelper.IsConstant(update.Type) && !builder.AsParameters.Contains(update))
            {
                builder.AsParameters.Add(update);
            }

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

            if (pi.NodeType != ExpressionType.MemberAccess)
            {
                throw new LinqException("Member expression expected for the 'Set' statement.");
            }

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

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

            var column = select.ConvertToSql(
                Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field);

            if (column.Length == 0)
            {
                throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, member.Name);
            }

            var expr = builder.ConvertToSql(select, update);

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

            select.SqlQuery.Set.Items.Add(new SqlQuery.SetExpression(column[0].Sql, expr));
        }
示例#8
0
        static ISqlPredicate MakeIsPredicate(ExpressionBuilder builder, IBuildContext context, Type fromType, Type toType)
        {
            var table          = new SqlTable(builder.MappingSchema, fromType);
            var mapper         = builder.MappingSchema.GetEntityDescriptor(fromType);
            var discriminators = mapper.InheritanceMapping;

            return(builder.MakeIsPredicate(context, discriminators, toType,
                                           name =>
            {
                var field = table.Fields.Values.First(f => f.Name == name);
                var member = field.ColumnDescriptor.MemberInfo;
                var expr = Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member);
                var sql = context.ConvertToSql(expr, 1, ConvertFlags.Field)[0].Sql;

                return sql;
            }));
        }
示例#9
0
        internal static void BuildSetter(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression setter,
            IBuildContext into,
            IBuildContext sequence)
        {
            if (setter.Body.NodeType != ExpressionType.MemberInit)
            {
                throw new LinqException("Object initializer expected for insert statement.");
            }

            var body = (MemberInitExpression)setter.Body;
            var ex   = body;
            var ctx  = new ExpressionContext(buildInfo.Parent, sequence, setter);

            for (var i = 0; i < ex.Bindings.Count; i++)
            {
                var binding = ex.Bindings[i];
                var member  = binding.Member;

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

                if (binding is MemberAssignment)
                {
                    var ma     = binding as MemberAssignment;
                    var column = into.ConvertToSql(
                        Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field);
                    var expr = builder.ConvertToSql(ctx, ma.Expression);

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

                    sequence.SqlQuery.Set.Items.Add(new SqlQuery.SetExpression(column[0].Sql, expr));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
示例#10
0
        internal static void BuildSetter(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression setter,
            IBuildContext into,
            List <SelectQuery.SetExpression> items,
            IBuildContext sequence)
        {
            var path = Expression.Parameter(setter.Body.Type, "p");
            var ctx  = new ExpressionContext(buildInfo.Parent, sequence, setter);

            if (setter.Body.NodeType == ExpressionType.MemberInit)
            {
                var ex = (MemberInitExpression)setter.Body;
                var p  = sequence.Parent;

                BuildSetter(builder, into, items, ctx, ex, path);

                builder.ReplaceParent(ctx, p);
            }
            else
            {
                var sqlInfo = ctx.ConvertToSql(setter.Body, 0, ConvertFlags.All);

                foreach (var info in sqlInfo)
                {
                    if (info.Members.Count == 0)
                    {
                        throw new LinqException("Object initializer expected for insert statement.");
                    }

                    if (info.Members.Count != 1)
                    {
                        throw new InvalidOperationException();
                    }

                    var member = info.Members[0];
                    var pe     = Expression.MakeMemberAccess(path, member);
                    var column = into.ConvertToSql(pe, 1, ConvertFlags.Field);
                    var expr   = info.Sql;

                    items.Add(new SelectQuery.SetExpression(column[0].Sql, expr));
                }
            }
        }
示例#11
0
        static void BuildSetter(
            ExpressionBuilder builder,
            IBuildContext into,
            List <SqlQuery.SetExpression> items,
            IBuildContext ctx,
            MemberInitExpression expression,
            Expression path)
        {
            foreach (var binding in expression.Bindings)
            {
                var member = binding.Member;

                if (member is MethodInfo)
                {
                    member = ((MethodInfo)member).GetPropertyInfo();
                }

                if (binding is MemberAssignment)
                {
                    var ma = binding as MemberAssignment;
                    var pe = Expression.MakeMemberAccess(path, member);

                    if (ma.Expression is MemberInitExpression && !into.IsExpression(pe, 1, RequestFor.Field).Result)
                    {
                        BuildSetter(
                            builder,
                            into,
                            items,
                            ctx,
                            (MemberInitExpression)ma.Expression, Expression.MakeMemberAccess(path, member));
                    }
                    else
                    {
                        var column = into.ConvertToSql(pe, 1, ConvertFlags.Field);
                        var expr   = builder.ConvertToSqlExpression(ctx, ma.Expression);

                        items.Add(new SqlQuery.SetExpression(column[0].Sql, expr));
                    }
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
示例#12
0
        internal static void ParseSet(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression extract,
            Expression update,
            IBuildContext select,
            List <SelectQuery.SetExpression> items)
        {
            var ext = extract.Body;

            if (!update.Type.IsConstantable() && !builder.AsParameters.Contains(update))
            {
                builder.AsParameters.Add(update);
            }

            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 = ((MethodInfo)member).GetPropertyInfo();
            }

            var column = select.ConvertToSql(body, 1, ConvertFlags.Field);

            if (column.Length == 0)
            {
                throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, member.Name);
            }

            var expr = builder.ConvertToSql(select, update);

            items.Add(new SelectQuery.SetExpression(column[0].Sql, expr));
        }
示例#13
0
        internal static void ParseSet(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression extract,
            LambdaExpression update,
            IBuildContext select)
        {
            var pi = extract.Body;

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

            if (pi.NodeType != ExpressionType.MemberAccess)
            {
                throw new LinqException("Member expression expected for the 'Set' statement.");
            }

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

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

            var sql    = select.SqlQuery;
            var column = sql.Set.Into != null ?
                         sql.Set.Into.Fields[member.Name] :
                         select.ConvertToSql(
                Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field)[0].Sql;
            var ctx  = new ExpressionContext(buildInfo.Parent, select, update);
            var expr = builder.ConvertToSql(ctx, update.Body);

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

            sql.Set.Items.Add(new SqlQuery.SetExpression(column, expr));
        }
示例#14
0
            public static List <Tuple <SqlInfo, SqlInfo> > MatchSequences(IBuildContext source, IBuildContext destination)
            {
                var sourceInfos = source.ConvertToSql(null, 0, ConvertFlags.All).ToList();
                var destInfos   = destination.ConvertToSql(null, 0, ConvertFlags.All).ToList();

                var result = new List <Tuple <SqlInfo, SqlInfo> >();

                foreach (var info in sourceInfos)
                {
                    if (info.MemberChain.Length == 0)
                    {
                        continue;
                    }

                    var destInfo = destInfos.FirstOrDefault(di => info.CompareMembers(di));

                    if (destInfo != null)
                    {
                        result.Add(Tuple.Create(info, destInfo));
                    }
                }

                return(result);
            }
示例#15
0
        internal static void ParseSet(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression extract,
            Expression update,
            IBuildContext select,
            SqlTable table,
            List <SqlQuery.SetExpression> items)
        {
            var ext = extract.Body;

            if (!ExpressionHelper.IsConstant(update.Type) && !builder.AsParameters.Contains(update))
            {
                builder.AsParameters.Add(update);
            }

            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);
            }

            ISqlExpression column;

            if (table != null)
            {
                column = table.Fields[name];
            }
            else
            {
                var sql = select.ConvertToSql(
                    body, 1, ConvertFlags.Field);
                //Expression.MakeMemberAccess(Expression.Parameter(member.DeclaringType, "p"), member), 1, ConvertFlags.Field)[0].Sql;

                if (sql.Length == 0)
                {
                    throw new LinqException("Member '{0}.{1}' is not a table column.", member.DeclaringType.Name, member.Name);
                }

                column = sql[0].Sql;
            }

            var expr = builder.ConvertToSql(select, update, false, false);

            SetConverter(builder.MappingSchema, member, expr);

            items.Add(new SqlQuery.SetExpression(column, expr));
        }
示例#16
0
        internal static void ParseSet(
            ExpressionBuilder builder,
            BuildInfo buildInfo,
            LambdaExpression extract,
            LambdaExpression update,
            IBuildContext select,
            SqlTable table,
            List <SelectQuery.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 = ((MethodInfo)member).GetPropertyInfo();
            }

            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 = ((MethodInfo)m).GetPropertyInfo();
                }

                return(m);
            })
                          .Where(m => m != null && !m.IsNullableValueMember())
                          .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);

            items.Add(new SelectQuery.SetExpression(column, expr));
        }