[英]Replace a type in an expression tree
我正在努力修改表達式樹。 我簡化了示例,使其更易於在此處顯示。 讓我們從兩個類開始:
public class Filter
{
public string FilterableProperty1 { get; set; }
public string FilterableProperty2 { get; set; }
}
public class Entity
{
public string FilterableProperty1 { get; set; }
public string FilterableProperty2 { get; set; }
public string NonFilterableProperty { get; set; }
}
Filter類中的所有屬性也存在於Entity類中。 現在,我想使用Filter類通過以下方法返回所需的實體:
public IEnumerable<Entity> GetEntities(Expression<Func<Filter, bool>> filter)
{
Expression<Func<Entity, bool>> convertedFilter = Expression.Lambda<Func<Entity, bool>>(
filter.Body,
Expression.Parameter(typeof(Entity), filter.Parameters[0].Name));
using (MyEntities entities = new MyEntities())
{
return entities.Entities.Where(convertedFilter);
}
}
所以基本上,我只是更改expression參數的類型。 現在,當我這樣調用函數時:
public IEnumerable<Entity> GetFilteredEntities()
{
return GetEntities(x => x.FilterableProperty1 == "Test");
}
我得到一個異常,說在指定的查詢表達式中找不到參數x。 顯然,通過替換ParameterExpression可以破壞一些東西。 如何創建具有正確類型的新表達式來接管(或重建)原始表達式的主體?
經過更多搜索后,我在這里找到了答案: 如何更改表達式樹中的類型? 。 當我提交問題時,它沒有出現在建議中。
因為我實際上並不需要Filter類,所以我只創建了一個我希望能夠過濾的屬性(IEntity)的接口,並修改了Entity類來實現它。 現在,我可以通過以下方式獲得所需的結果:
// Example use: return entities.Entities.Where(ExpressionTransformer<IEntity,Entity>.Transform(filter));
internal static class ExpressionTransformer<TFrom, TTo> where TTo : TFrom
{
public class Visitor : ExpressionVisitor
{
private ParameterExpression _parameter;
public Visitor(ParameterExpression parameter)
{
_parameter = parameter;
}
protected override Expression VisitParameter(ParameterExpression node)
{
return _parameter;
}
}
public static Expression<Func<TTo, bool>> Tranform(Expression<Func<TFrom, bool>> expression)
{
ParameterExpression parameter = Expression.Parameter(typeof(TTo));
Expression body = new Visitor(parameter).Visit(expression.Body);
return Expression.Lambda<Func<TTo, bool>>(body, parameter);
}
}
萬一您需要做類似的事情但不能使用接口或無法使類實現該接口:答案也在上述答案中
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.