首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >替换表达式树中的类型

替换表达式树中的类型
EN

Stack Overflow用户
提问于 2013-06-11 02:54:47
回答 1查看 4.5K关注 0票数 3

我正在纠结于表达式树的修改。我简化了示例,使其更容易在此处显示。让我们从两个类开始:

代码语言:javascript
运行
复制
    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类通过如下方法返回所需的实体:

代码语言:javascript
运行
复制
    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);
        }
    }

所以基本上我只是改变了表达式参数的类型。现在,当我像这样调用函数时:

代码语言:javascript
运行
复制
    public IEnumerable<Entity> GetFilteredEntities()
    {
        return GetEntities(x => x.FilterableProperty1 == "Test");
    }

我得到一个异常,说明在指定的查询表达式中找不到参数x。显然,通过替换ParameterExpression,我正在破坏一些东西。如何创建具有正确类型的新表达式,以接管(或重建)原始表达式的正文?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-11 04:02:56

经过进一步搜索,我在这里找到了答案:How to change a type in an expression tree?。当我提交我的问题时,它没有出现在建议中。

因为我并不真正需要Filter类,所以我创建了一个只具有我希望能够过滤的属性(IEntity)的接口,并修改了Entity类以实现它。现在,我可以使用下面的代码获得所需的结果:

代码语言:javascript
运行
复制
// 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);
    }
}

如果你需要做一些类似的事情,但是你不能使用一个接口,或者你不能让你的类实现那个接口:答案也在上面提到的答案中

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17030821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档