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();            
}