Beispiel #1
0
        public IEnumerable <T> CreateSplittedEnumerable <TInner>(MethodCallExpression call, Expression innerExpression)
        {
            IEnumerable <TInner> enumerable = Query.Provider.CreateQuery <TInner>(innerExpression);
            // We need to ask for the GetEnumerator to be able to check the query
            // This call will throw if the LINQ-to-SQL can't produce the query
            IEnumerator <TInner> enumerator = enumerable.GetEnumerator();
            // Success!
            // We transform back the enumerator to an enumerable
            IEnumerable <TInner> enumerable2 = new FakeEnumerable <TInner>(enumerator, enumerable);
            // "Quick-n-dirty". We use a fake Queryable. The "right" way would probably be
            // transform all the outer query from IQueryable.Method<T> to IEnumerable.Method<T>
            // Too much long :)
            // Note that this Queryable is executed in "local" (the AsQueryable<T> method is nearly
            // useless... The second time in my life I was able to use it for something)
            IQueryable <TInner> queryable = Queryable.AsQueryable(enumerable2);
            // We rebuild a new expression by changing the "old" inner parameter
            // of the MethodCallExpression with the queryable we just
            // built
            Expression expression2 = new SimpleExpressionReplacer {
                Call = call, Queryable = queryable
            }.Visit(Query.Expression);
            // We "execute" locally the whole query through a second
            // "outer" instance of the EnumerableQuery (this class is
            // the class that "implements" the "fake-magic" of AsQueryable)
            EnumerableQuery <T> query2 = new EnumerableQuery <T>(expression2);

            // And we return an enumerator to it
            return(query2.AsEnumerable());
        }
Beispiel #2
0
    public static void Main(string[] args)
    {
        Expression <Func <TheObject, int, bool> > myExpression = (myObj, theType) => myObj.Prop > theType;

        int value = 123;

        var body = myExpression.Body;

        var body2 = new SimpleExpressionReplacer(myExpression.Parameters[1], Expression.Constant(value)).Visit(body);

        Expression <Func <TheObject, bool> > myExpression2 = Expression.Lambda <Func <TheObject, bool> >(body2, myExpression.Parameters[0]);
    }
Beispiel #3
0
        protected override Expression VisitMember(MemberExpression node)
        {
            PropertyInfo property = node.Member as PropertyInfo;
            MethodInfo   getter;

            // We handle only properties (that aren't indexers) that have
            // a get
            if (property != null && property.GetIndexParameters().Length == 0 && (getter = property.GetGetMethod(true)) != null)
            {
                // We work only on methods marked as [ExpandableAttribute]
                var attribute = property.GetCustomAttributes(typeof(ExpandableAttribute), false).FirstOrDefault();
                if (attribute != null)
                {
                    string name      = property.Name + ExpandableAttribute.ExpandableSuffix;
                    var    property2 = property.DeclaringType.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, null, Type.EmptyTypes, null);
                    if (property2 == null || property2.GetGetMethod(true) == null)
                    {
                        if (property2 == null)
                        {
                            if (property.DeclaringType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, null, Type.EmptyTypes, null) != null)
                            {
                                throw new NotSupportedException(string.Format("{0}.{1} isn't static!", property.DeclaringType.FullName, name));
                            }
                            throw new NotSupportedException(string.Format("{0}.{1} not found!", property.DeclaringType.FullName, name));
                        }
                        // property2.GetGetMethod(true) == null
                        throw new NotSupportedException(string.Format("{0}.{1} doesn't have a getter!", property.DeclaringType.FullName, name));
                    }
                    // Instance Parameters have the additional
                    // "parameter" of the declaring type
                    var argumentsPlusReturnTypes = getter.IsStatic ?
                                                   new[] { node.Type } :
                    new[] { property.DeclaringType, node.Type };
                    var funcType   = typeof(Func <>).Assembly.GetType(string.Format("System.Func`{0}", argumentsPlusReturnTypes.Length));
                    var returnType = typeof(Expression <>).MakeGenericType(funcType.MakeGenericType(argumentsPlusReturnTypes));
                    if (property2.PropertyType != returnType)
                    {
                        throw new NotSupportedException(string.Format("{0}.{1} has wrong return type!", property.DeclaringType.FullName, name));
                    }
                    var expression = (LambdaExpression)property2.GetValue(null, null);
                    // Instance Members have the additional "parameter"
                    // of the declaring type
                    var arguments2 = getter.IsStatic ? new Expression[0] : new[] { node.Expression };
                    var replacer   = new SimpleExpressionReplacer(expression.Parameters, arguments2);
                    var body       = replacer.Visit(expression.Body);
                    return(this.Visit(body));
                }
            }
            return(base.VisitMember(node));
        }
Beispiel #4
0
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            MethodInfo method = node.Method;
            // We work only on methods marked as [ExpandableAttribute]
            var attribute = method.GetCustomAttributes(typeof(ExpandableAttribute), false).FirstOrDefault();

            if (attribute != null)
            {
                string name    = method.Name + ExpandableAttribute.ExpandableSuffix;
                var    method2 = method.DeclaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
                if (method2 == null)
                {
                    if (method.DeclaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null) != null)
                    {
                        throw new NotSupportedException(string.Format("{0}.{1} isn't static!", method.DeclaringType.FullName, name));
                    }
                    throw new NotSupportedException(string.Format("{0}.{1} not found!", method.DeclaringType.FullName, name));
                }
                // Instance methods have the additional "parameter" of
                // the declaring type
                var argumentsPlusReturnTypes = method.IsStatic ?
                                               node.Arguments.Select(x => x.Type).Concat(new[] { node.Type }).ToArray() :
                                               new[] { method.DeclaringType }.Concat(node.Arguments.Select(x => x.Type)).Concat(new[] { node.Type }).ToArray();
                var funcType   = typeof(Func <>).Assembly.GetType(string.Format("System.Func`{0}", argumentsPlusReturnTypes.Length));
                var returnType = typeof(Expression <>).MakeGenericType(funcType.MakeGenericType(argumentsPlusReturnTypes));
                if (method2.ReturnType != returnType)
                {
                    throw new NotSupportedException(string.Format("{0}.{1} has wrong return type!", method.DeclaringType.FullName, name));
                }
                var expression = (LambdaExpression)method2.Invoke(null, null);
                // Instance methods have the additional "parameter" of
                // the declaring type
                var arguments2 = method.IsStatic ? node.Arguments : new[] { node.Object }.Concat(node.Arguments);
                var replacer = new SimpleExpressionReplacer(expression.Parameters, arguments2);
                var body     = replacer.Visit(expression.Body);
                return(this.Visit(body));
            }
            return(base.VisitMethodCall(node));
        }