删除部分表达式

本文关键字:表达式 删除部 | 更新日期: 2023-09-27 18:03:23

我有一个通用方法:

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

结果表达式包含将T转换为IEntity: e => Convert(e)。Id我想删除这个类型转换(使EF能够生成SQL)。换句话说,我想将Convert(e)替换为e。

删除部分表达式

如果我们假设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);

我已经做了ExpressionVisitor:

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

ExpressionVisitor<T>只是ExpressionVisitor的一个方便的包装。

如果你知道更好的方法,请贴出来。