IQueryable.QueryProvider.CreateQuery异常:";参数表达式无效;

本文关键字:参数 表达式 无效 quot QueryProvider CreateQuery 异常 IQueryable | 更新日期: 2023-09-27 18:25:44

下面的代码位于从List继承的泛型类T中,因此我对对象一无所知,也就是为什么我要向方法传递列名。

Exception几乎出现在该方法的最后一行。

 public decimal? Max (string column) 
    {
        IQueryable<T> queryableData = this.AsQueryable<T>();
        // Compose the expression tree that represents the parameter to the predicate.
        ParameterExpression pe = Expression.Parameter(typeof(T), "item");
        // ***** Select(item => item.[column]) *****
        // Create an expression tree that represents the expression 'item.[column] == "id"'
        Expression left = null;
        try
        {
            left = Expression.Property(pe, typeof(T).GetProperty(column, System.Type.EmptyTypes));
        }
        catch
        {
        }
        // Create an expression tree that represents the expression
        // 'queryableData.Select(item => item.[column]) '
        MethodCallExpression whereCallExpression = null;
        try
        {
            whereCallExpression = Expression.Call(
                typeof(Queryable),
                "Select",
                new Type[] { queryableData.ElementType, typeof(int) },
                queryableData.Expression,
                Expression.Lambda<Func<T, int>>(left, new ParameterExpression[] { pe }));
        }
        catch
        {
        }
        IQueryable<T> results = null;
            string lexpression = whereCallExpression.ToString();
            // Create an executable query from the expression tree.
            //Exception at this line of Code:
             results= queryableData.Provider.CreateQuery<T>(whereCallExpression);
        return Convert.ToInt32(results.Max());
    }

传入的表达式(即where CallEWexpression)似乎是正确的,但不断出现此异常:"参数表达式无效"。我真的陷入了困境,一直没能找到解决方案。

此外,如果有人知道实现这一目标的更好方法,请告诉我——这是我所能想到的。

谢谢,

Roberto

编辑:CallExpression可能错误的构造。那么,问题是如何解决它。这真的是我无法理解的困难。

编辑2:删除try-catch块-仅用于调试目的。

IQueryable.QueryProvider.CreateQuery异常:";参数表达式无效;

为了回答您的"实现这一目标的更好方法",并假设您在计算Max时知道T是什么,为什么不使用内置的IEnumerable.Max()扩展方法?假设您的类继承自List<T>,就像您在问题开头所说的那样,这应该有效:

var myClass = new YourClass<Person>(); // obviously this would have been initialized and filled elsewhere
var maxAge = myClass.Max(p => p.Age); //Assuming Person has an Age property

如果你在课堂上真的需要这个,你可以在课堂上做这样的事情(提前测试代码):

public class myClass<T> : List<T> {
    private readonly Func<T, decimal> _fieldGetter;
    public myClass(Func<T, decimal> fieldGetter) {
         _fieldGetter = fieldGetter;
    }
    // then your Max becomes:
    public decimal? Max() {
        return this.Max(i => _fieldGetter(i));
    }
}

已解决!!

答案就在我面前…感谢Chris Shain让我走上了正确的轨道

var result =this.Select(c => c.GetType().GetProperty(column).GetValue(c, null));
return (int)result.Max();