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