![](/img/trans.png)
[英]Mapping generic properties with reflection / Cast property to a generic type
[英]Cast of generic property through reflection
我正在尝试通过其名称检索DbContext DbSet属性,但是我不知道如何处理通用参数。
DataSource.Load(IQuerable source)方法来自外部dll,我无法对其进行修改。
知道我的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>)
更新
更清楚地说:DataSourceLoader.Load从实体集中加载数据; 我不在乎返回类型,因为它将被序列化并发送到客户端插件。
客户端插件使用entitySet名称作为参数通过ajax调用请求数据。 我不想为我拥有的每个实体集使用不同的方法(或较长的switch语句)并静态调用DataSource.Load方法。
我想解析要在运行时查询的实体集
以我的理解,问题是如何在运行时调用通用方法。
通过获取通用的MethodInfo
定义,通过MakeGenericMethod
调用绑定通用参数并通过Invoke
方法调用它,可以通过反射来实现。
具体的答案取决于许多因素,例如该方法是静态的还是实例的,名称是否唯一(重载)等。您可以在“使用反射选择正确的通用方法”中查看有关该方法的更多详细信息,但以最简单的形式是这样的:
var elementType = ((IQueryable)source).ElementType;
var loadMethod = typeof(DataSourceLoader).GetMethod("Load")
.MakeGenericMethod(elementType);
return loadMethod.Invoke(null, new object[] { source });
通过利用DLR快速动态调度和调用功能,可以避免所有这些复杂情况。 在这种情况下,您所需要做的就是将其简单地转换为dynamic
:
return DataSourceLoader.Load((dynamic)source);
您可以尝试使用此方法:
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.