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