X是变量,但是在尝试强制类型转换时像类型一样使用 [英] X is a variable but used like a type when trying to cast
问题描述
我正在传递要查询的实体类型名称的字符串,并基于该字符串获取类型。我想找回 DbSet
并返回一个 IQueryable
。问题是我在做(DbSet< tableEntity>)
并收到以下错误:
I am passing a string of the name of the entity type I want to query and getting the type based on the string. I want to get the DbSet
back and return an IQueryable
. The problem is where I am doing (DbSet<tableEntity>)
and getting the following error:
tableEntity是一个变量,但在尝试强制转换时像类型
tableEntity is a variable but used like a type
一样使用。有没有办法解决这个问题?
when trying to cast. Is there a way to resolve this?
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();
}
编辑
只是要补充一点,我无法访问类型,即我正在通过字符串传递名称。
Just to add I don't have access to the type that's we I am passing the name through a string.
推荐答案
事实证明,实体类型在编译时实际上是未知的或不可知的。它必须是一个字符串。
So it turns out that the entity type is literally not known, or knowable, at compile time. It has to be a string.
在编译时使用类型的唯一地方是强制转换为(DbSet< tableEntity>)
。好吧,您可能不需要。该类型所需的全部就是调用 AsQueryable()
,而 AsQueryable()
是<$的扩展方法c $ c> IEnumerable ,具有通用和非通用版本。如果我们通过非泛型 IEnumerable
调用它,那就是非泛型 AsQueryable()
,返回非泛型 IQueryable
。但是我们还是要返回 object
,所以,嘿。为了使此事情有用,无论如何,某处的某处必须进行大量反射,因此声明的类型可能影响不大。
The only place you're using the type at compile time is in the cast to (DbSet<tableEntity>)
. Well, you may not need that. All you need from that type is to call AsQueryable()
, and AsQueryable()
is an extension method for IEnumerable
, with generic and non-generic versions. IF we call it through non-generic IEnumerable
, that's non-generic AsQueryable()
, returning non-generic IQueryable
. But we're returning object
anyway, so hey. For the result of this thing to be useful, something somewhere must be doing a fair amount of reflection on it anyway, so the declared type is likely to be of little consequence.
查看是否可行:
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> ;
,我们必须使用反射来获取 AsQueryable< TEntityType>
的 MethodInfo
(在编译时)为未知的实体类型,并在其上调用 MakeGenericMethod(tableEntity)
。
If it turns out you need generic IQueryable<TEntityType>
, we'll have to use reflection to get MethodInfo
for AsQueryable<TEntityType>
for the unknown (at compile time) entity type, and call MakeGenericMethod(tableEntity)
on that.
第一次尝试:
在语言中,键入参数泛型必须是实际类型,而不是 Type
类的实例。那是因为它们在编译时已解决。
In the language, type parameters to generics must be actual types, not instances of the Type
class. That's because they're resolved at compile time.
但这没问题;要将类型参数传递给泛型方法,只需编写带有类型参数的泛型方法即可。
But that's no problem; to pass a type parameter to a generic method, simply write a generic method with a type parameter.
您不能这样做:
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()
的原因。
Reflection is different; that's why we pass typeof(TTableEntity)
to MakeGenericMethod()
.
一旦我们使用了编译器可以检查的实际类型,我们也可以使用返回类型做得更好:
And once we're using an actual type that the compiler can check, we can do better with our return type, too:
public IQueryable<TTableEntity> GetList<TTableEntity>()
{
var dbObject = (DbSet<TTableEntity>)typeof(DbContext)
.GetMethod("Set", Type.EmptyTypes)
.MakeGenericMethod(typeof(TTableEntity))
.Invoke(databaseContext, null);
return dbObject.AsQueryable();
}
这篇关于X是变量,但是在尝试强制类型转换时像类型一样使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!