X是变量,但是在尝试强制类型转换时像类型一样使用 [英] X is a variable but used like a type when trying to cast

查看:137
本文介绍了X是变量,但是在尝试强制类型转换时像类型一样使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在传递要查询的实体类型名称的字符串,并基于该字符串获取类型。我想找回 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆