X 是一个变量,但在尝试转换时像类型一样使用
X is a variable but used like a type when trying to cast
我传递的是我要查询的实体类型名称的字符串,并根据该字符串获取类型。我想取回 DbSet
和 return 一个 IQueryable
。问题是我在哪里做 (DbSet<tableEntity>)
并收到以下错误:
tableEntity is a variable but used like a type
尝试投射时。有办法解决这个问题吗?
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();
}
编辑
只是补充一下,我无法访问我们正在通过字符串传递名称的类型。
因此事实证明,实体类型在编译时实际上是未知的或可知的。它必须是一个字符串。
您在编译时唯一使用该类型的地方是转换为 (DbSet<tableEntity>)
。好吧,你可能不需要那个。您需要从该类型调用 AsQueryable()
,而 AsQueryable()
是 IEnumerable
的扩展方法,具有通用和非通用版本。如果我们通过非泛型 IEnumerable
调用它,那就是非泛型 AsQueryable()
,returning 非泛型 IQueryable
。但是我们 returning 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
for AsQueryable<TEntityType>
for unknown (at compile time) entity type,并且打电话给 MakeGenericMethod(tableEntity)
。
第一次尝试:
在该语言中,泛型的类型参数必须是实际类型,而不是Type
class 的实例。那是因为它们是在编译时解决的。
但这没问题;要将类型参数传递给泛型方法,只需编写一个带有类型参数的泛型方法。
你不能这样做:
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()
的原因。
一旦我们使用编译器可以检查的实际类型,我们也可以使用我们的 return 类型做得更好:
public IQueryable<TTableEntity> GetList<TTableEntity>()
{
var dbObject = (DbSet<TTableEntity>)typeof(DbContext)
.GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(typeof(TTableEntity))
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
因为正如 Ed 提到的那样,您在编译时不使用 table 实体类型,为什么不直接使用非泛型 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();
}
我传递的是我要查询的实体类型名称的字符串,并根据该字符串获取类型。我想取回 DbSet
和 return 一个 IQueryable
。问题是我在哪里做 (DbSet<tableEntity>)
并收到以下错误:
tableEntity is a variable but used like a type
尝试投射时。有办法解决这个问题吗?
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();
}
编辑
只是补充一下,我无法访问我们正在通过字符串传递名称的类型。
因此事实证明,实体类型在编译时实际上是未知的或可知的。它必须是一个字符串。
您在编译时唯一使用该类型的地方是转换为 (DbSet<tableEntity>)
。好吧,你可能不需要那个。您需要从该类型调用 AsQueryable()
,而 AsQueryable()
是 IEnumerable
的扩展方法,具有通用和非通用版本。如果我们通过非泛型 IEnumerable
调用它,那就是非泛型 AsQueryable()
,returning 非泛型 IQueryable
。但是我们 returning 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
for AsQueryable<TEntityType>
for unknown (at compile time) entity type,并且打电话给 MakeGenericMethod(tableEntity)
。
第一次尝试:
在该语言中,泛型的类型参数必须是实际类型,而不是Type
class 的实例。那是因为它们是在编译时解决的。
但这没问题;要将类型参数传递给泛型方法,只需编写一个带有类型参数的泛型方法。
你不能这样做:
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()
的原因。
一旦我们使用编译器可以检查的实际类型,我们也可以使用我们的 return 类型做得更好:
public IQueryable<TTableEntity> GetList<TTableEntity>()
{
var dbObject = (DbSet<TTableEntity>)typeof(DbContext)
.GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(typeof(TTableEntity))
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
因为正如 Ed 提到的那样,您在编译时不使用 table 实体类型,为什么不直接使用非泛型 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();
}