如果我理解正确的话,你有LambdaExpression
,而不是Expression<Func<T, bool>>
,你想用它作为Where
但IQueryable
(其中DbSet
类实现),而不是IQueryable<T>
。
您只需要知道IQueryable<T>
扩展方法只需将MethodCallExpression
发送到查询表达式树中对应的Queryable
方法即可。
例如,要效仿IQueryable
Where
或Select
您可以使用下面的自定义扩展方法:
public static class QueryableExtensions
{
public static IQueryable Where(this IQueryable source, LambdaExpression predicate)
{
var expression = Expression.Call(
typeof(Queryable), "Where",
new Type[] { source.ElementType },
source.Expression, Expression.Quote(predicate));
return source.Provider.CreateQuery(expression);
}
public static IQueryable Select(this IQueryable source, LambdaExpression selector)
{
var expression = Expression.Call(
typeof(Queryable), "Select",
new Type[] { source.ElementType, selector.Body.Type },
source.Expression, Expression.Quote(selector));
return source.Provider.CreateQuery(expression);
}
}
你可以做需要的其他Queryable
方法类似。
更新:既然你是在有趣,这里是一个使用表达式的原型获得泛型方法定义,并从它构建的通用方法的一个例子:
public static class QueryableExtensions
{
static MethodInfo QueryableMethod<T>(this Expression<Func<IQueryable<object>, T>> prototype, params Type[] types)
{
return ((MethodCallExpression)prototype.Body).Method
.GetGenericMethodDefinition()
.MakeGenericMethod(types);
}
public static IQueryable Where(this IQueryable source, LambdaExpression predicate)
{
var expression = Expression.Call(
QueryableMethod(q => q.Where(x => true), source.ElementType),
source.Expression, Expression.Quote(predicate));
return source.Provider.CreateQuery(expression);
}
public static IQueryable Select(this IQueryable source, LambdaExpression selector)
{
var expression = Expression.Call(
QueryableMethod(q => q.Select(x => 1), source.ElementType, selector.Body.Type),
source.Expression, Expression.Quote(selector));
return source.Provider.CreateQuery(expression);
}
}
如何创建'表达 >'如果你不知道'T'? –
@IvanStoev您可以使用类型创建表达式。 – oscilatingcretin
像返回'LambdaExpression'的非泛型'Expression.Lambda'?你想将它绑定到“Where”? –