コード例 #1
0
ファイル: ProxyQueryProvider.cs プロジェクト: zyj0021/ALinq
        IQueryable IQueryProvider.CreateQuery(Expression expression)
        {
            var elementType = ExpressionUtility.ElementType(expression);
            var queryable   = CreateQuery(expression, elementType);

            return(queryable);
        }
コード例 #2
0
ファイル: ProxyQueryProvider.cs プロジェクト: zyj0021/ALinq
            protected override Expression VisitMethodCall(MethodCallExpression m)
            {
                var anonymousType = typeof(DataRow);

                if (m.Method.Name == "Cast")
                {
                    var castSourceType = ExpressionUtility.ElementType(m.Arguments[0]);
                    var castTargetType = ExpressionUtility.ElementType(m);
                    if (castTargetType.IsAssignableFrom(anonymousType))
                    {
                        this.typePaires.Add(castSourceType, castTargetType);
                    }
                }
                return(base.VisitMethodCall(m));
            }
コード例 #3
0
ファイル: ProxyQueryProvider.cs プロジェクト: zyj0021/ALinq
        TResult IQueryProvider.Execute <TResult>(Expression expression)
        {
            expression = UpdateExpression(expression);

            var isSingleValue = !typeof(IEnumerable).IsAssignableFrom(expression.Type) || expression.Type == typeof(string);

            if (isSingleValue)
            {
                var obj = this.source.Execute <TResult>(expression);
                return(obj);
            }

            var castSourceType = ExpressionUtility.ElementType(expression);
            var castTargetType = GetElementType(typeof(TResult));

            if (castSourceType != castTargetType)
            {
                expression = Expression.Call(typeof(Queryable), "Cast", new[] { castTargetType }, expression);
            }

            var items = this.source.Execute <TResult>(expression);

            return(items);
        }
コード例 #4
0
ファイル: ProxyQueryProvider.cs プロジェクト: zyj0021/ALinq
            protected override Expression VisitMethodCall(MethodCallExpression m)
            {
                //==============================================================
                // 说明:将索引器字段转换为类的属性或字段
                if (m.Method.Name == "get_Item" && m.Object != null && m.Object.Type == this.oldType)
                {
                    Debug.Assert(m.Arguments.Count == 1);
                    var arg = m.Arguments[0];

                    Debug.Assert(arg.NodeType == ExpressionType.Constant);
                    Debug.Assert(arg.Type == typeof(string));

                    var name = (string)((ConstantExpression)arg).Value;
                    var pf   = TypeUtility.FindPropertyOrField(this.newType, name, false);
                    if (pf == null)
                    {
                        throw Error.NoPublicPropertyOrField(name, newType);
                    }

                    Expression expr = Expression.MakeMemberAccess(this.parameter, pf);
                    if (m.Type != expr.Type)
                    {
                        expr = Expression.Convert(expr, m.Type);
                    }

                    return(expr);
                }
                //==============================================================



                //==============================================================
                // 说明:如果序列的实际类型与 Cast 的目标类型一致,则直接返回序列,而不进行转换。
                // 例如:
                // var q = db.CreateQuery("select p from Products as p").Cast<Product>();
                // 由于序列的实际类型即是Product,因为,Cast 是多余的,直接除。即变为:
                // db.CreateQuery("select p from Products as p")
                //--------------------------------------------------------------
                if (m.Method.Name == "Cast")
                {
                    var castSourceType = ExpressionUtility.ElementType(m.Arguments[0]);
                    var castTargetType = ExpressionUtility.ElementType(m);
                    if (this.newType == castSourceType && this.oldType == castTargetType)
                    {
                        return(m.Arguments[0]);
                    }
                }
                //==============================================================


                Expression instance = Visit(m.Object);
                IEnumerable <Expression> arguments = VisitExpressionList(m.Arguments);

                if ((instance == m.Object) && (arguments == m.Arguments))
                {
                    return(m);
                }

                //==============================================================
                // 说明:替换掉原来的类型
                // 例如:
                // var q = db.CreateQuery<IDataRecord>("select p from Products as p")
                // 变为
                // q = db.CreateQuery<Product>()
                if (m.Method.IsGenericMethod)
                {
                    var argTypes = m.Method.GetGenericArguments();
                    if (argTypes[0] == oldType)
                    {
                        var methodName  = m.Method.Name;
                        var declareType = m.Method.DeclaringType;
                        argTypes[0] = newType;
                        var expr = Expression.Call(declareType, methodName, argTypes, arguments.ToArray());
                        return(expr);
                    }
                }
                //==============================================================



                return(Expression.Call(instance, m.Method, arguments));
            }