Удалить часть выражения - PullRequest
1 голос
/ 22 июля 2011

У меня есть универсальный метод:

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.

Ответы [ 2 ]

1 голос
/ 22 июля 2011

Если мы предположим 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);
0 голосов
/ 22 июля 2011

Я сделал это ExpressionVisitor:

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

ExpressionVisitor<T> - просто удобная обёртка для ExpressionVisitor.

Если вы знаете лучшие способы - пожалуйста, напишите это.

...