我传递了一个我要查询的实体类型名称的字符串,并根据字符串获取类型。我希望返回DbSet
并返回IQueryable
。问题是我正在做(DbSet<tableEntity>)
并收到以下错误:
tableEntity是一个变量,但像类型一样使用
试图施法时。有办法解决这个问题吗?
public object GetList(string tableEntity)
{
Type tableEntity = Type.GetType("TestProject." + typeName + ", TestProject");
var dbObject = (DbSet<tableEntity>)typeof(DbContext).GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(tableEntity)
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
修改
只是要添加我无法访问我们通过字符串传递名称的类型。
答案 0 :(得分:5)
因此事实证明,在编译时,实体类型在字面上是未知的或可知的。它必须是一个字符串。
您在编译时使用该类型的唯一位置是转换为(DbSet<tableEntity>)
。好吧,你可能不需要那个。您只需拨打AsQueryable()
,AsQueryable()
就是IEnumerable
的扩展方法,具有通用和非通用版本。如果我们通过非通用IEnumerable
调用它,那就是非通用AsQueryable()
,返回非通用IQueryable
。但是我们无论如何都要回归object
,所以嘿。为了使这个东西变得有用,某些东西必须在它上面进行相当多的反思,所以声明的类型可能没那么重要。
看看是否有效:
public object GetList(string typeName)
{
Type tableEntity = Type.GetType("TestProject." + typeName + ", TestProject");
var dbObject = (System.Collections.IEnumerable)
typeof(DbContext).GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(tableEntity)
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
如果事实证明您需要通用IQueryable<TEntityType>
,那么我们必须使用反射为MethodInfo
获取AsQueryable<TEntityType>
未知(在编译时)实体类型,并且就此致电MakeGenericMethod(tableEntity)
。
首先尝试:
在该语言中,对泛型的类型参数必须是实际类型,而不是Type
类的实例。这是因为它们在编译时已经解决了。
但那没问题;要将类型参数传递给泛型方法,只需使用类型参数编写泛型方法即可。
你不能这样做:
var stuff = GetList("MyTableEntityClass");
但这也很好:
var stuff = GetList<MyTableEntityClass>();
...
public object GetList<TTableEntity>()
{
var dbObject = (DbSet<TTableEntity>)typeof(DbContext)
.GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(typeof(TTableEntity))
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
反思不同;这就是我们将typeof(TTableEntity)
传递给MakeGenericMethod()
的原因。
一旦我们使用了编译器可以检查的实际类型,我们也可以使用返回类型做得更好:
public IQueryable<TTableEntity> GetList<TTableEntity>()
{
var dbObject = (DbSet<TTableEntity>)typeof(DbContext)
.GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(typeof(TTableEntity))
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
答案 1 :(得分:1)
因为,正如Ed所说,你不在编译时使用表实体类型,为什么不使用非泛型databaseContext.Set (tableEntity).AsQueryable ()
?但是,如果你已经放心Set<>
,请试试这个:
public object GetList(string tableEntity)
{
Type tableEntity = Type.GetType("TestProject." + typeName + ", TestProject");
return GetType ()
.GetMethod ("GetListHelper")
.MakeGenericMethod (tableEntity)
.Invoke (this) ;
}
public object GetListHelper<T> () where T : class
{
var dbObject = databaseContext.Set<T> (null) ;
return dbObject.AsQueryable();
}