簡體   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