Sie können die folgenden Hilfsfunktionen (je einer wahrscheinlich ihnen einen besseren Namen geben könnte , aber das ist nicht unbedingt erforderlich):
public static class ExpressionUtils
{
public static Expression<Func<TOuter, TResult>> Bind<TOuter, TInner, TResult>(this Expression<Func<TOuter, TInner>> source, Expression<Func<TInner, TResult>> resultSelector)
{
var body = new ParameterExpressionReplacer { source = resultSelector.Parameters[0], target = source.Body }.Visit(resultSelector.Body);
var lambda = Expression.Lambda<Func<TOuter, TResult>>(body, source.Parameters);
return lambda;
}
public static Expression<Func<TOuter, TResult>> ApplyTo<TInner, TResult, TOuter>(this Expression<Func<TInner, TResult>> source, Expression<Func<TOuter, TInner>> innerSelector)
{
return innerSelector.Bind(source);
}
class ParameterExpressionReplacer : ExpressionVisitor
{
public ParameterExpression source;
public Expression target;
protected override Expression VisitParameter(ParameterExpression node)
{
return node == source ? target : base.VisitParameter(node);
}
}
}
Let sehen, wie die Probe Ausdruck
c.Criteria = x => x.Name.StartsWith("SomeTexts");
kann aus den zwei verschiedenen Teilen gebaut werden.
Wenn Sie
Expression<Func<Customer, string>> e = x => x.Name;
dann
c.Criteria = e.Bind(x => x.StartsWith("SomeTexts"));
oder wenn Sie diese stattdessen
Expression<Func<string, bool>> e = x => x.StartsWith("SomeTexts");
dann
c.Criteria = e.ApplyTo((Customer x) => x.Name);
Wenn Sie beide Ausdrücke haben, können Sie eine der beiden Funktionen verwenden, da a.Bind(b)
b.ApplyTo(a)
entspricht.
Ist 'p' ein' Ausdruck> 'oder ein' Func '? –
gmiley
Sollen 'c.Criteria = x.Name.StartWith (" SomeTexts ");' be 'c.Criteria = x => x.Name.StartWith (" SomeTexts ");'? –
@YacoubMassad: Sie haben Recht :) – Masoud