Assume that we have two classes
public class EntityA
{
public EntityB EntityB { get; set; }
}
public class EntityB
{
public string Name { get; set; }
public bool IsDeleted { get; set; }
}
And two expressions for selector and predicator
Expression<Func<EntityA, EntityB>> selector = c => c.EntityB;
Expression<Func<EntityB, bool>> predicate = c => c.IsDeleted && c.Name == "AAA";
I need write a method that returns composed expression like a
Expression<Func<TSource, bool>> Compose<TPropType>(Expression<Func<TSource, TPropType>> selector, Expression<Func<TPropType, bool>> predicator)
{
// Expression API ???
}
In my example result should be
Expression<Func<EntityA, bool>> exp = Compose(selector, predicate);
what is equivalent to
Expression<Func<EntityA, bool>> exp = c => c.EntityB.IsDeleted && c.EntityB.Name == "AAA";
You can try the following:
static Expression<Func<TSource, bool>> Compose<TSource, TPropType>(
Expression<Func<TSource, TPropType>> selector,
Expression<Func<TPropType, bool>> predicator)
{
ParameterExpression param = Expression.Parameter(typeof(TSource), "sourceObj");
Expression invokedSelector = Expression.Invoke(selector, new Expression[] { param });
Expression invokedPredicate = Expression.Invoke(predicator, new[] { invokedSelector });
return Expression.Lambda<Func<TSource, bool>>(invokedPredicate, new[] { param });
}
Here's how to use it:
static void Main()
{
Expression<Func<EntityA, EntityB>> selector = c => c.EntityB;
Expression<Func<EntityB, bool>> predicate = c => c.IsDeleted && c.Name == "AAA";
Expression<Func<EntityA, bool>> exp = Compose(selector, predicate);
System.Console.WriteLine(exp.Compile()(new EntityA()));
}