X是一个变量,但在尝试投射时像一个类型一样使用

Kog*_*oth 2 c# reflection types dbset

我传递了一个我要查询的实体类型名称的字符串,并根据字符串获取类型.我想得到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();            
}
Run Code Online (Sandbox Code Playgroud)

编辑

只是要添加我无法访问我们通过字符串传递名称的类型.

15e*_*153 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();            
}
Run Code Online (Sandbox Code Playgroud)

如果事实证明你需要通用的IQueryable<TEntityType>,我们将不得不使用反射来获取MethodInfoAsQueryable<TEntityType>未知(在编译时)实体类型,并呼吁MakeGenericMethod(tableEntity)这一点.


第一次尝试:

在该语言中,泛型的类型参数必须是实际类型,而不是Type类的实例.那是因为它们在编译时得到了解决.

但那不是问题; 要将类型参数传递给泛型方法,只需使用类型参数编写泛型方法即可.

你不能这样做:

var stuff = GetList("MyTableEntityClass");
Run Code Online (Sandbox Code Playgroud)

但这也很好:

var stuff = GetList<MyTableEntityClass>();
Run Code Online (Sandbox Code Playgroud)

...

public object GetList<TTableEntity>()
{
    var dbObject = (DbSet<TTableEntity>)typeof(DbContext)
                        .GetMethod("Set", Type.EmptyTypes)
                        .MakeGenericMethod(typeof(TTableEntity))
                        .Invoke(databaseContext, null);

    return dbObject.AsQueryable();            
}
Run Code Online (Sandbox Code Playgroud)

反思是不同的; 这就是我们传递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();            
}
Run Code Online (Sandbox Code Playgroud)