繁体   English   中英

通过反思来铸造一般财产

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM