我有一些(非)通用函数显式分配给DbSet
(使用 Entity Framework 6.1 ,但问题在某种意义上更通用):
//Non-generic type method
public static IQueryable BuildQuery(this DbSet dbSet)
{
return dbSet;
}
//Generic base class elements method
public static IQueryable<Entity> BuildQuery(this DbSet<Entity> dbSet)
{
return dbSet.Include(de1 => de1.NavigationPropertyBase);
}
//Derived class 1 elements method
public static IQueryable<DerivedEntity1> BuildQuery(this DbSet<DerivedEntity1> dbSet)
{
return dbSet.Include(de1 => de1.NavigationPropertyX);
}
//Derived class 2 elements method
public static IQueryable<DerivedEntity2> BuildQuery(this DbSet<DerivedEntity2> dbSet)
{
return dbSet.Include(de2 => de2.NavigationPropertyX).
Include(de2 => de2.NavigationPropertyY);
}
我知道虽然DerivedEntity1
和DerivedEntity2
延伸Entity
,但Dbset<DerivedEntityX>
不会延伸DbSet<Entity>
。
我想要做的是,基于泛型类型实现后期绑定之类的行为。我想将泛型类型放入非泛型变量中,然后调用BuildQuery
方法(在编译时可见非泛型类型):
//This compiles with no errors.
DbSet dbSetNonGeneric = dbSet; // dbSet is of DbSet<DerivedEntity1> type
var result = dbSetNonGeneric.BuildQuery();
我的问题是,这会导致根据泛型类型调用BuildQuery
方法还是会调用非泛型方法?在第二种情况下,有没有办法实现这种方法调用?
答案 0 :(得分:1)
这会导致根据泛型类型调用BuildQuery方法还是会调用非泛型方法?
它将使用非泛型重载。
在第二种情况下,有没有办法实现这种方法调用?
您可以将变量键入dynamic
,但结果也会为dynamic
。
您也可以使用反射来确定dbSetNonGeneric
的类型,您想要使用的重载,以及在对象上调用该重载。
更新:由于动态查找无法找到扩展方法(link),因此应将这些方法用作常规静态方法,以便与dynamic
结合使用。
答案 1 :(得分:0)
它将调用非泛型方法。原因很简单,扩展方法基于变量类型而不是运行时类型(派生类型)调用
根据@Servy的建议你可以使用反射,但我怀疑dynamic
。
如果您有扩展程序,dynamic
关键字将无效。
要用反射调用,你必须做点工作。实际上当反射被使用时它不会是实例方法的一部分,但它就像你用来创建扩展方法的静态类的静态方法。
以下链接将帮助您获取该方法并使用反射调用。