我需要使用反射执行一些链式方法。
我想要获得的是一个未知编译类型的实体核心DBContext集的IQueryable:
var type = typeof(x);
this.DBContext.Set(type).AsQueryable();
显然,该代码无法编译,因为Set是一个通用方法,其中必须在编译时定义类型:
this.DBContext.Set<TUnknownType>().AsQueryable();
为了解决这个问题,我尝试使用反射执行方法:
MethodInfo dbSetMethod = typeof(DbContext).GetMethod(nameof(DbContext.Set));
MethodInfo generic = dbSetMethod.MakeGenericMethod(property.DeclaringType);
var asQueryableMethod = generic.ReturnType.GetMethod("AsQueryable");
var result = asQueryableMethod.Invoke(this.DbContext, null);
但是当我调试代码时,我在行中得到一个null:
var asQueryableMethod = generic.ReturnType.GetMethod("AsQueryable");
显然,dbContext.Set<TUnknownType>()
没有AsQueryable方法。那个方法是来自Linq的扩展方法我想。
我错过了什么?为什么方法不可用?
答案 0 :(得分:3)
没错,DbSet<T>
实施IQueryable<T>
,这会公开AsQueryable<T>()
extension method。
C#提供了两种调用扩展方法的方法 - 作为实例方法,即
this.DBContext.Set<UnknownType>().AsQueryable();
或作为静态方法,即
Queryable.AsQueryable(this.DBContext.Set<UnknownType>());
另一方面,反射API仅支持第二种方法,即获取和调用该方法的静态方法方式。对于通用MethodInfo
,您应该获得Queryable.AsQueryable
,并向其传递适当的泛型类型参数,以使MethodInfo
对象适合于调用。