Remove part of Expression
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.
精彩评论