开发者

Remove part of Expression

开发者 https://www.devze.com 2023-03-22 08:14 出处:网络
I have a generic method: public void ExpressionBuilder<T>() where T: IEntity { Expression<Func<T, long>> expr = e => e.Id; //Id is part of IEntity

I have a generic method:

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

The resulted expression contains casting of T to IEntity: e 开发者_运维百科=> Convert(e).Id I want to remove this casting (to make it possible for EF to generate SQL). In other words I would like to replace Convert(e) by e.


If we assume a public long Id {get;} on T, and the expression is that simple, then maybe just build it manually:

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

A visitor should work for more complex examples; for example:

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);
    }
}

and

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


I have done it by ExpressionVisitor:

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

ExpressionVisitor<T> is just an convenient wrapper for ExpressionVisitor.

If you know better ways - please post it.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号