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块-仅用于调试目的。
为了回答您的"实现这一目标的更好方法",并假设您在计算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();