I have following code:
public class MyClass<T>
{
Expression<Func<T,bool>> Criteria {get; set;}
}
public class Customer
{
//..
public string Name {get; set;}
}
and use it as following:
var c = new MyClass<Customer>();
c.Criteria = x.Name.StartWith("SomeTexts");
Is there any way to define something like this:
? p = x=>x.Customer.Name;
var c = new MyClass<Customer>();
c.Criteria = p => p.StartWith("SomeTexts");
I used Expression<Func<T,bool>> to use it as where clause in my linq to entities query (EF code first).
You can use the following helper functions (one could probably give them a better names, but that's not essential):
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 see how the sample expression
c.Criteria = x => x.Name.StartsWith("SomeTexts");
can be built from the two different parts.
If you have
Expression<Func<Customer, string>> e = x => x.Name;
then
c.Criteria = e.Bind(x => x.StartsWith("SomeTexts"));
or if you have this instead
Expression<Func<string, bool>> e = x => x.StartsWith("SomeTexts");
then
c.Criteria = e.ApplyTo((Customer x) => x.Name);
If you have both expressions, then you can use any of the two functions, since a.Bind(b) is equivalent to b.ApplyTo(a).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With