我正在尝试按名称检索DbContext DbSet属性,但我不知道如何处理泛型参数。
DataSource.Load(IQuerable source)方法来自外部DLL,我无法修改它。
知道我的DbSet prop的属性名称(来自实体框架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 name作为参数通过ajax调用请求数据。我不想为我拥有的每个实体集使用不同的方法(或long switch语句),并静态调用DataSource.Load方法。
我想解析在运行时查询的实体集
答案 0 :(得分:2)
我理解它的方式,问题是如何在运行时调用泛型方法。
通过获取通用MethodInfo
定义,通过MakeGenericMethod
调用绑定泛型参数并通过Invoke
方法调用它,可以通过反射来实现。
具体答案取决于许多因素,例如方法是静态还是实例,名称是否唯一(重载)等。您可以在Select Right Generic Method with Reflection中查看有关该方法的更多详细信息,但最简单的形式它会是这样的:
var elementType = ((IQueryable)source).ElementType;
var loadMethod = typeof(DataSourceLoader).GetMethod("Load")
.MakeGenericMethod(elementType);
return loadMethod.Invoke(null, new object[] { source });
使用DLR Fast Dynamic Dispatch and Invocation功能可以避免所有复杂情况。在这种情况下,您只需要简单地转换为dynamic
:
return DataSourceLoader.Load((dynamic)source);
答案 1 :(得分:0)
您可以尝试使用此方法:
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);
}