我正在尝试开发一个应用Where子句的泛型函数,但“inputQuery.Where(condition)”语句不能编译。我得到“参数2:无法从'System.Linq.Expressions.LambdaExpression'转换为'System.Linq.Expressions.Expression< System.Func< object,bool>>'。
public IQueryable<Object> ExecuteWhereClause(IQueryable<Object> inputQuery, Object typedValue, Type viewType, String paramName, Type paramType)
{
ParameterExpression parameter = Expression.Parameter(viewType);
Type[] typeArgs = { viewType, typeof(bool) };
var condition =
Expression.Lambda(
typeof(Func<,>).MakeGenericType(typeArgs),
Expression.Equal(
Expression.Property(parameter, paramName),
Expression.Constant(typedValue, paramType)
),
parameter
);
return inputQuery.Where(condition);
}
答案 0 :(得分:0)
您正在构建lambda,它需要viewType,它不能与Object一起使用。如果你想这样做,你必须施展它
public IQueryable<Object> ExecuteWhereClause(IQueryable<Object> inputQuery, Object typedValue, Type viewType, String paramName, Type paramType)
{
ParameterExpression parameter = Expression.Parameter(typeof(Object));
var condition =
Expression.Lambda<Func<Object, bool>>(
Expression.Equal(
Expression.Property(Expression.Convert(parameter, viewType), paramName),
Expression.Constant(typedValue, paramType)
),
parameter
);
return inputQuery.Where(condition);
}
答案 1 :(得分:0)
我觉得你对Where
的表达方式有点困惑。
谓词参数具体类型
Expression<Func<TSource, bool>> predicate
其中TSource
- 在coolection中的元素类型,在您的情况下,您有集合IQueryable<Object> inputQuery
,因此TSource
始终为Object
和返回值的静态类型 - bool
。
因此,即使您以某种方式将通用LambdaExpression
转换为Expression<Func<Object, bool>>
,也会收到错误,因为viewType
可能不是Object
。
您可以解决此问题,只需创建键入的LambdaExpression
var condition =
Expression.Lambda<Func<object,bool>>(
Expression.Equal(
Expression.Property(parameter, paramName),
Expression.Constant(typedValue, paramType)
),
parameter
);
但现在如果viewType
不是Object
类型''的ParameterExpression不能用于'System.Object'类型的委托参数
所以你有一个方法:
第一:无法使用viewType
并且总是使用object
,在这种情况下,在尝试获取属性时会出现另一个错误,因为您只能获得具有object
类的属性。
第二:稍微改变你的功能以使用通用参数
IQueryable<Object>
- &gt; IQueryable<T>
使用此T
ParameterExpression parameter = Expression.Parameter(typeof(T));
因为您只能将此类型的参数传递给可用Expression.Lambda<Func<T,bool>>
函数的lambda Where
。
使用Expression.Lambda<Func<T,bool>>
- 所以这真的需要Where
- 在源集合中使用元素类型的可用对象。
所以最后你可以获得下一个功能:
public static IQueryable<T> ExecuteWhereClause<T>(IQueryable<T> inputQuery, object typedValue, String paramName)
{
ParameterExpression parameter = Expression.Parameter(typeof(T));
var condition =
Expression.Lambda<Func<T,bool>>(
Expression.Equal(
Expression.Property(parameter, paramName),
Expression.Constant(typedValue)
),
parameter
);
return inputQuery.Where(condition);
}
甚至
public static IQueryable<T> ExecuteWhereClause<T,U>(IQueryable<T> inputQuery, U typedValue, String paramName)
{
ParameterExpression parameter = Expression.Parameter(typeof(T));
var condition =
Expression.Lambda<Func<T,bool>>(
Expression.Equal(
Expression.Property(parameter, paramName),
Expression.Constant(typedValue)
),
parameter
);
return inputQuery.Where(condition);
}