Пример #1
0
        private Expression ApplyFilters(Expression node)
        {
            var nodeElementType = node.Type.GetElementTypeIfCollection();

            if (_expressions.Keys.Any(x => x == _pathSoFar + node.ToString().Replace(ProjectToParameterName, string.Empty)))
            {
                var exp = _expressions[_pathSoFar + node.ToString().Replace(ProjectToParameterName, string.Empty)] as LambdaExpression;

                Expression newExp = null;

                //See if there's an applicable root filter to combine with the .With expression
                var parameterType = exp.Parameters[0].Type.GetElementTypeIfCollection();
                if (_rootFilters != null && _rootFilters.ContainsKey(parameterType))
                {
                    //Combine the 2 filtering expressions
                    var lamb = _rootFilters[parameterType] as LambdaExpression;
                    newExp = ParameterReplacer.Replace(exp.Body, exp.Parameters.First(), lamb.Body);

                    MethodCallExpression arg = null;
                    if ((newExp as MethodCallExpression).Arguments[0].NodeType == ExpressionType.Call)
                    {
                        arg = ((newExp as MethodCallExpression).Arguments[0] as MethodCallExpression);
                    }
                    else
                    {
                        arg = ((newExp as MethodCallExpression).Arguments[0] as UnaryExpression).Operand as MethodCallExpression;
                    }

                    Expression param = arg;

                    while (param.NodeType != ExpressionType.Parameter)
                    {
                        param = (param as MethodCallExpression).Arguments[0];
                    }

                    //combine the new expression with the existing member access expression
                    newExp = ParameterReplacer.Replace(newExp, param as ParameterExpression, node);
                }
                else //no root filter, just use the .With expression
                {
                    //combine the single filtering expression with the existing member access expression
                    newExp = ParameterReplacer.Replace(exp.Body, exp.Parameters.First(), node);
                }
                return(newExp);
            }
            else if (_rootFilters != null && _rootFilters.ContainsKey(nodeElementType))//see if there's an applicable root filter to use
            {
                var lamb = _rootFilters[nodeElementType] as LambdaExpression;

                //combine the single filtering expression with the existing member access expression
                var newExp = ParameterReplacer.Replace(lamb.Body, lamb.Parameters.First(), node);

                return(newExp);
            }
            else //nothing to apply, just continue
            {
                return(node);
            }
        }
Пример #2
0
        protected override Expression VisitConstant(ConstantExpression node)
        {
            if (node.Type.IsGenericType && node.Type.GetGenericTypeDefinition() == typeof(ObjectQuery <>))
            { //this is the root node. Need to transform any applicable root filter and apply it.
                var elementType = node.Type.GetElementTypeIfCollection();
                if (_rootFilters.ContainsKey(elementType))
                {
                    var lamb = _rootFilters[elementType] as LambdaExpression;

                    var casted = Expression.Convert(lamb.Body, typeof(ObjectQuery <>).MakeGenericType(elementType));

                    //combine the single filtering expression with the existing member access expression
                    var composed = ParameterReplacer.Replace(casted, lamb.Parameters.First(), node);

                    return(composed);
                }
            }
            return(base.VisitConstant(node));
        }