public override DbExpression Visit(DbMemberExpression exp)
        {
            if (exp.Expression != null)
            {
                DbExpression caller = exp.Expression.Accept(this);
                if (caller != exp.Expression)
                {
                    exp = DbExpression.MemberAccess(exp.Member, caller);
                }
            }

            if (exp.Expression != null)
            {
                if (!IsConstantOrParameter(exp.Expression))
                {
                    return(exp);
                }
            }

            MemberInfo member = exp.Member;

            if (this.CanTranslateToSql(exp))
            {
                return(exp);
            }

            return(DbExpression.Parameter(exp.Evaluate(), exp.Type));
        }
Beispiel #2
0
        public DbExpression GetDbExpression(MemberExpression memberExpressionDeriveParameter)
        {
            Stack <MemberExpression> memberExpressions = ExpressionExtensions.Reverse(memberExpressionDeriveParameter);

            DbExpression             ret = null;
            IMappingObjectExpression moe = this;

            foreach (MemberExpression memberExpression in memberExpressions)
            {
                MemberInfo member = memberExpression.Member;

                if (moe == null && ret != null)
                {
                    /* a.F_DateTime.Value.Date */
                    ret = DbExpression.MemberAccess(member, ret);
                    continue;
                }

                DbExpression e = moe.GetMemberExpression(member);
                if (e == null)
                {
                    moe = moe.GetNavMemberExpression(member);
                    if (moe == null)
                    {
                        if (ret == null)
                        {
                            throw new Exception();
                        }
                        else
                        {
                            ret = DbExpression.MemberAccess(member, ret);
                            continue;
                        }
                    }

                    if (ret != null)
                    {
                        throw new NotSupportedException(memberExpressionDeriveParameter.ToString());
                    }
                }
                else
                {
                    if (ret != null)
                    {
                        throw new NotSupportedException(memberExpressionDeriveParameter.ToString());
                    }

                    ret = e;
                }
            }

            if (ret == null)
            {
                throw new Exception(memberExpressionDeriveParameter.ToString());
            }

            return(ret);
        }
        public DbExpression GetDbExpression(MemberExpression memberExpressionDeriveParameter)
        {
            Stack <MemberExpression> memberExpressions = ExpressionExtension.Reverse(memberExpressionDeriveParameter);

            if (memberExpressions.Count == 0)
            {
                throw new Exception();
            }

            DbExpression ret = this._exp;

            foreach (MemberExpression memberExpression in memberExpressions)
            {
                MemberInfo member = memberExpression.Member;
                ret = DbExpression.MemberAccess(member, ret);
            }

            if (ret == null)
            {
                throw new Exception(memberExpressionDeriveParameter.ToString());
            }

            return(ret);
        }
Beispiel #4
0
        public void Process(DbMethodCallExpression exp, SqlGeneratorBase generator)
        {
            generator.SqlBuilder.Append("SUBSTRING(");
            exp.Object.Accept(generator);
            generator.SqlBuilder.Append(",");

            DbExpression arg1 = exp.Arguments[0];

            if (arg1.NodeType == DbExpressionType.Constant)
            {
                int startIndex = (int)(((DbConstantExpression)arg1).Value) + 1;
                generator.SqlBuilder.Append(startIndex.ToString());
            }
            else
            {
                arg1.Accept(generator);
                generator.SqlBuilder.Append(" + 1");
            }

            generator.SqlBuilder.Append(",");
            if (exp.Method == PublicConstants.MethodInfo_String_Substring_Int32)
            {
                var string_LengthExp = DbExpression.MemberAccess(PublicConstants.PropertyInfo_String_Length, exp.Object);
                string_LengthExp.Accept(generator);
            }
            else if (exp.Method == PublicConstants.MethodInfo_String_Substring_Int32_Int32)
            {
                exp.Arguments[1].Accept(generator);
            }
            else
            {
                throw new NotSupportedException(exp.Method.Name);
            }

            generator.SqlBuilder.Append(")");
        }
Beispiel #5
0
        bool IsDateSubtract(DbMemberExpression exp)
        {
            MemberInfo member = exp.Member;

            if (member.DeclaringType == PublicConstants.TypeOfTimeSpan)
            {
                if (exp.Expression.NodeType == DbExpressionType.Call)
                {
                    DbMethodCallExpression dbMethodExp = (DbMethodCallExpression)exp.Expression;
                    if (dbMethodExp.Method == PublicConstants.MethodInfo_DateTime_Subtract_DateTime)
                    {
                        int?intervalDivisor = null;

                        if (member == UtilConstants.PropertyInfo_TimeSpan_TotalDays)
                        {
                            intervalDivisor = 24 * 60 * 60 * 1000;
                            goto appendIntervalTime;
                        }
                        if (member == UtilConstants.PropertyInfo_TimeSpan_TotalHours)
                        {
                            intervalDivisor = 60 * 60 * 1000;
                            goto appendIntervalTime;
                        }
                        if (member == UtilConstants.PropertyInfo_TimeSpan_TotalMinutes)
                        {
                            intervalDivisor = 60 * 1000;
                            goto appendIntervalTime;
                        }
                        if (member == UtilConstants.PropertyInfo_TimeSpan_TotalSeconds)
                        {
                            intervalDivisor = 1000;
                            goto appendIntervalTime;
                        }
                        if (member == UtilConstants.PropertyInfo_TimeSpan_TotalMilliseconds)
                        {
                            intervalDivisor = 1;
                            goto appendIntervalTime;
                        }

                        return(false);

appendIntervalTime:
                        this.CalcDateDiffPrecise(dbMethodExp.Object, dbMethodExp.Arguments[0], intervalDivisor.Value);
                        return(true);
                    }
                }
                else
                {
                    DbSubtractExpression dbSubtractExp = exp.Expression as DbSubtractExpression;
                    if (dbSubtractExp != null && dbSubtractExp.Left.Type == PublicConstants.TypeOfDateTime && dbSubtractExp.Right.Type == PublicConstants.TypeOfDateTime)
                    {
                        DbMethodCallExpression dbMethodExp = new DbMethodCallExpression(dbSubtractExp.Left, PublicConstants.MethodInfo_DateTime_Subtract_DateTime, new List <DbExpression>(1)
                        {
                            dbSubtractExp.Right
                        });
                        DbMemberExpression dbMemberExp = DbExpression.MemberAccess(member, dbMethodExp);
                        dbMemberExp.Accept(this);

                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #6
0
        DbExpression Process_MemberAccess_Which_Link_First_Or_FirstOrDefault(MemberExpression exp)
        {
            /*
             * 判断是不是 First().xx,FirstOrDefault().xx 之类的
             * First().Name: 泛型参数如果不是复杂类型,则转成 Select(a=> a.Name).First()
             * First().xx.Name:  如果 xx 是复杂类型,则转成 Select(a=> a.xx.Name).First()
             * First().xx.Name.Length:  如果 xx 是复杂类型,则转成 Select(a=> a.xx.Name).First().Length
             */

            // 分割
            MethodCallExpression     methodCall = null;
            Stack <MemberExpression> memberExps = new Stack <MemberExpression>();

            Expression e = exp;

            while (e.NodeType == ExpressionType.MemberAccess)
            {
                MemberExpression memberExpression = (MemberExpression)e;
                memberExps.Push(memberExpression);
                e = memberExpression.Expression;
            }

            methodCall = (MethodCallExpression)e;
            methodCall = OptimizeCondition(methodCall);

            if (!MappingTypeSystem.IsMappingType(methodCall.Type))
            {
                /*
                 * query.First().xx.Name.Length --> query.Select(a=> a.xx.Name).First().Length
                 */

                ParameterExpression parameter    = Expression.Parameter(methodCall.Type, "a");
                Expression          selectorBody = parameter;
                while (memberExps.Count != 0)
                {
                    MemberExpression memberExpression = memberExps.Pop();
                    selectorBody = Expression.MakeMemberAccess(parameter, memberExpression.Member);

                    if (MappingTypeSystem.IsMappingType(selectorBody.Type))
                    {
                        break;
                    }
                }

                Type             delegateType = typeof(Func <,>).MakeGenericType(parameter.Type, selectorBody.Type);
                LambdaExpression selector     = Expression.Lambda(delegateType, selectorBody, parameter);
                var selectMethod = methodCall.Object.Type.GetMethod("Select");
                selectMethod = selectMethod.MakeGenericMethod(selectorBody.Type);
                var selectMethodCall = Expression.Call(methodCall.Object, selectMethod, Expression.Quote(selector)); /* query.Select(a=> a.xx.Name) */

                var sameNameMethod     = selectMethodCall.Type.GetMethod(methodCall.Method.Name, Type.EmptyTypes);
                var sameNameMethodCall = Expression.Call(selectMethodCall, sameNameMethod); /* query.Select(a=> a.xx.Name).First() */

                methodCall = sameNameMethodCall;
            }

            DbExpression dbExpression = this.Visit(methodCall);

            while (memberExps.Count != 0)
            {
                MemberExpression memberExpression = memberExps.Pop();
                dbExpression = DbExpression.MemberAccess(memberExpression.Member, dbExpression);
            }

            return(dbExpression);
        }
        public DbExpression GetDbExpression(MemberExpression memberExpressionDeriveFromParameter)
        {
            Stack <MemberExpression> memberExpressions = ExpressionExtension.Reverse(memberExpressionDeriveFromParameter);

            DbExpression             ret = null;
            IMappingObjectExpression moe = this;

            foreach (MemberExpression memberExpression in memberExpressions)
            {
                MemberInfo accessedMember = memberExpression.Member;

                if (moe == null && ret != null)
                {
                    /* a.F_DateTime.Value.Date */
                    ret = DbExpression.MemberAccess(accessedMember, ret);
                    continue;
                }

                /* **.accessedMember */
                DbExpression e = moe.GetMappingMemberExpression(accessedMember);
                if (e == null)
                {
                    /* Indicate current accessed member is not mapping member, then try get complex member like 'a.Order' */
                    moe = moe.GetComplexMemberExpression(accessedMember);

                    if (moe == null)
                    {
                        if (ret == null)
                        {
                            /*
                             * If run here,the member access expression must be like 'a.xx',
                             * and member 'xx' is neither mapping member nor complex member,in this case,we not supported.
                             */
                            throw new InvalidOperationException(memberExpressionDeriveFromParameter.ToString());
                        }
                        else
                        {
                            /* Non mapping member is not found also, then convert linq MemberExpression to DbMemberExpression */
                            ret = DbExpression.MemberAccess(accessedMember, ret);
                            continue;
                        }
                    }

                    if (ret != null)
                    {
                        /* This case and case #110 will not appear in normal, if you meet,please email me([email protected]) or call 911 for help. */
                        throw new InvalidOperationException(memberExpressionDeriveFromParameter.ToString());
                    }
                }
                else
                {
                    if (ret != null)//Case: #110
                    {
                        throw new InvalidOperationException(memberExpressionDeriveFromParameter.ToString());
                    }

                    ret = e;
                }
            }

            if (ret == null)
            {
                /*
                 * If run here,the input argument 'memberExpressionDeriveFromParameter' expression must be like 'a.xx','a.**.xx','a.**.**.xx' ...and so on,
                 * and the last accessed member 'xx' is not mapping member, in this case, we not supported too.
                 */
                throw new InvalidOperationException(memberExpressionDeriveFromParameter.ToString());
            }

            return(ret);
        }