删除表达式的一部分

时间:2011-07-22 07:00:51

标签: c# .net expression-trees

我有一个通用的方法:

public void ExpressionBuilder<T>() where T: IEntity
{
   Expression<Func<T, long>> expr = e => e.Id; //Id is part of IEntity
   ...
}

结果表达式包含将T转换为IEntity:e =&gt;转换(E).ID 我想删除此转换(以使EF可以生成SQL)。换句话说,我想用e。

取代Convert(e)

2 个答案:

答案 0 :(得分:1)

如果我们在public long Id {get;}上假设T,并且表达式很简单,那么可能只需手动构建它:

var param = Expression.Parameter(typeof (T), "e");
var lambda = Expression.Lambda<Func<T, long>>(
          Expression.PropertyOrField(param,"Id"), param);

访客应该为更复杂的例子工作;例如:

internal class FlattenInterface<T> : ExpressionVisitor
{
    protected override Expression VisitMember(MemberExpression node)
    {
        if(node.Member.DeclaringType == typeof(T))
        {
            return Expression.MakeMemberAccess(
                node.Expression,
                node.Expression.Type.GetMember(node.Member.Name).Single());
        }
        return base.VisitMember(node);
    }
}

var direct = (Expression<Func<T, long>>)new FlattenInterface<IEntity>()
       .Visit(expr);

答案 1 :(得分:0)

我是通过ExpressionVisitor完成的:

expr = ExpressionVisitor<UnaryExpression>.Visit(expr, p => return p.Operand);

ExpressionVisitor<T>只是ExpressionVisitor的便捷包装。

如果您了解更好的方法 - 请发布。