使用
IQueryable<T> query - where T : BaseEntity
我有以下代码,用于通用方法 - 使用反射调用 .Where() 方法(这是有效的):
var predicate = Expression.Lambda(body, item);
MethodInfo whereCall = (typeof(Queryable).GetMethods().First(mi => mi.Name == "Where" && mi.GetParameters().Length == 2).MakeGenericMethod(query.ElementType));
MethodCallExpression call = Expression.Call(whereCall, new Expression[] { query.Expression, predicate });
query = query.Provider.CreateQuery<T>(call);
我想使用这样的东西(并避免反射):
var predicate = Expression.Lambda<Func<T, bool>>(body, item);
query = query.Where(predicate);
但此代码的问题在于 T 被用作基本类型,而不是派生类型在运行时。
如何将 T 转换为 query.ElementType(派生类型)?
最佳答案
你的第二段代码确实比第一段好。您将需要以某种方式 使用反射调用Expression.Lambda
方法。一个方便的方法是这样的:
static IQueryable<T> CreateQuery<T>(IQueryable<T> query, ...) {
var predicate = Expression.Lambda<Func<T, bool>>(body, item);
query = query.Where(predicate);
return query;
}
使用 T 作为派生类型调用此方法。您可以使用 MakeGenericMethod
执行该调用。根据您的情况,可能足以说明:
CreateQuery((dynamic)query);
关于C# 表达式转换为派生类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35391210/