[英]Cast of generic property through reflection
I'm trying to retrieving a DbContext DbSet property by its name but I don't know how to handle the generic parameter. 我正在尝试通过其名称检索DbContext DbSet属性,但是我不知道如何处理通用参数。
DataSource.Load(IQuerable source) method comes from an external dll and I cannot modify it. DataSource.Load(IQuerable source)方法来自外部dll,我无法对其进行修改。
Knowing the property name of my DbSet prop (from an entity framework dbcontext class) I want to use that property value as parameter for DataSource.Load 知道我的DbSet属性的属性名称(从实体框架dbcontext类),我想将该属性值用作DataSource.Load的参数
public class DataManager
{
private MyDbContext _dbContext;
public DataManager(MyDbContext dbContext)
{
_dbContext = dbContext;
}
public object Load(string propName)
{
var source = _dbContext.GetType().GetProperty(entityName).GetValue(_dbContext, null);
return DataSourceLoader.Load(source);
}
//DataSourceLoader.Load signature:
//DataSourceLoader.Load<T>(System.Linq.IQueryable<T>)
Update 更新
To be more clear: DataSourceLoader.Load loads data from an entity set; 更清楚地说:DataSourceLoader.Load从实体集中加载数据; I don't care of the return type because it will be serialized and sent to a client plugin.
我不在乎返回类型,因为它将被序列化并发送到客户端插件。
A client plugin requests the data by an ajax call using the entitySet name as parameter. 客户端插件使用entitySet名称作为参数通过ajax调用请求数据。 I don't want to have a different method (or a long switch statement) for each entity set I have and statically invoke the DataSource.Load method.
我不想为我拥有的每个实体集使用不同的方法(或较长的switch语句)并静态调用DataSource.Load方法。
I would like to resolve the entity set to query at runtime 我想解析要在运行时查询的实体集
The way I understand it, the question is how to call a generic method at runtime. 以我的理解,问题是如何在运行时调用通用方法。
It's possible to do that with reflection by obtaining the generic MethodInfo
definition, binding the generic arguments via MakeGenericMethod
call and invoking it via Invoke
method. 通过获取通用的
MethodInfo
定义,通过MakeGenericMethod
调用绑定通用参数并通过Invoke
方法调用它,可以通过反射来实现。
The concrete answer depends on many factors like if the method is static or instance, if the name is unique or not (overloads) etc. You can see more details about that in Select Right Generic Method with Reflection , but in the simplest form it would be something like this: 具体的答案取决于许多因素,例如该方法是静态的还是实例的,名称是否唯一(重载)等。您可以在“使用反射选择正确的通用方法”中查看有关该方法的更多详细信息,但以最简单的形式是这样的:
var elementType = ((IQueryable)source).ElementType;
var loadMethod = typeof(DataSourceLoader).GetMethod("Load")
.MakeGenericMethod(elementType);
return loadMethod.Invoke(null, new object[] { source });
You can avoid all that complications by utilizing the DLR Fast Dynamic Dispatch and Invocation feature. 通过利用DLR快速动态调度和调用功能,可以避免所有这些复杂情况。 All you need in this case is a simple cast to
dynamic
: 在这种情况下,您所需要做的就是将其简单地转换为
dynamic
:
return DataSourceLoader.Load((dynamic)source);
You could try with this method: 您可以尝试使用此方法:
public object Load(string setName)
{
var property = _context.GetType().GetProperties()
.SingleOrDefault(p => p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericArguments()[0].GetProperty(setName) != null);
return property.GetValue(_context) ?? throw new ArgumentOutOfRangeException(setName);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.