开发者

LINQ Expression Problem

I have a Linq Expression that is giving me a real headache and hope someone can help me find out why my provider does not like it.

If I do the following it works fine;

Expression<Func<Employee, bool>> expr = e => e.Participant == "Y";
_context.Employees.Where(expr).ToList<IEmployee>();

However, if I do the following my provider doesn't like it.

Expression<Func<IEmployee, bool>> expr = e => e.Participant == "Y";

Expression<Func<Employee, bool>> convertedExpr = ParameterReplacer.Replace
          <Func<IEmployee, bool>, Func<Employee, bool>> 
          (expr,
          expr.Parameters.Single(), 
          Expression.Parameter(typeof(Employee)));

_context.Employees.Where(convertedExpr).ToList<IEmployee>();

The reason I am doing the conversion is that the upper layer of my application only knows about the interface type, so I convert it to a Expression that uses the concrete type in the lower layer using the ParameterReplacer (kindly supplied by another SO member).

I have compared the linq expressions between the version that works and the one that doesn't and the only difference I can see is in what I see in the DebugView property in that the parameter names are different.

Here is the code for the ParameterReplacer;

public static class ParameterReplacer
{
    // Produces an expression identical to 'expression'
    // except with 'source' parameter replaced with 'target' parameter.
    public static Expression<TOutput> Replace<TInput, TOutput>(Expression<TInput> expression, ParameterExpression source, ParameterExpression target)
    { 
        return new ParameterReplacerVisitor<TOutput>(source, target).VisitAndConvert(expression);
    } 

    private class ParameterReplacerVisitor<TOutput> : ExpressionVisitor
    {         
        private ParameterExpression _source;
        private ParameterExpression _target;

        public ParameterReplacerVisitor(ParameterExpression source, ParameterExpression target)
        {             
            _source = source; 
            _target = target;
        } 

        internal Expression<TOutput> VisitAndConvert<T>(Expression<T> root)
        {             
            return (Expression<TOutput>)VisitLambda(root);
        }          

        protected override Expression VisitLambda<T>(Expression<T> node)
        {             
            // Leave all parameters alone except the one we want to replace.
            var parameters = node.Parameters.Select(p => p == _source ? _target : p);
            return Expression.Lambda<TOutput>(Visit(node.Body), parameters);
        }          

        protected override Expression VisitParameter(ParameterExpression node)
        { 
            // Replace the source with the target, visit other params as usual.
            return node == _source ? _target : base.VisitParameter(node);
        }
    } 
}

Is this an issue with the ParameterReplacer or my provider? Can any one help me out?

The provider I am using is Telerik OpenAccess and the exception its throwing is;

InnerException: System.NullReferenceException Message=Object reference not set to an instance of an object. Source=Telerik.OpenAccess.35.Extensions StackTrace: at Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQueryImpl(Type type, Int32 elementAt, O开发者_StackOverflow社区bject[] groupResolutionParamValues, Boolean single, Boolean checkOid) at Telerik.OpenAccess.Query.ExpressionCompiler.PerformDatabaseQuery(Type type, Int32 elementAt, Object[] groupResolutionParamValues, Boolean single, Boolean checkOid) InnerException:


I have never used your provider, so I can't be sure, but considering the circumstances, I think this is good bet:

Since, the only difference is that the parameter in the second expression has null Name and the exception you are getting is a null reference exception, I think that's exactly the problem. Try changing the Name to something non-null.

That means changing the creation of the new parameter to something like:

Expression.Parameter(typeof(Employee), "e")
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜