예제 #1
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();
                }
            }
        }
예제 #2
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, false);

            builder.ReplaceParent(ctx, sp);

            SetConverter(builder.MappingSchema, member, expr);

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