using System.Collections.Generic;
using System.Linq.Expressions;
private static readonly List<Merchant> Merchants = new List<Merchant> { new Merchant { ExternalId = "1", Name = "Foo" }, new Merchant { ExternalId = "2", Name = "Bar" } };
public static void Main()
Console.WriteLine(Get(m => m.ExternalId == "2").Name);
private static Merchant Get(Expression<Func<MerchantViewModel, bool>> predicate)
return Merchants.AsQueryable().SingleOrDefault(predicate.CastParameter<MerchantViewModel, Merchant>());
public string ExternalId { get; set; }
public string Name { get; set; }
public class MerchantViewModel
public string ExternalId { get; set; }
public static class PredicateMapper
public static Expression<Func<TTo, bool>> CastParameter<TFrom, TTo>(this Expression<Func<TFrom, bool>> predicate)
var parameter = Expression.Parameter(typeof(TTo));
var body = new ParameterReplacer<TTo>(parameter).Visit(predicate.Body);
return Expression.Lambda<Func<TTo, bool>>(body, parameter);
private class ParameterReplacer<TTo> : ExpressionVisitor
private readonly ParameterExpression parameter;
public ParameterReplacer(ParameterExpression parameter)
this.parameter = parameter;
protected override Expression VisitParameter(ParameterExpression node)
protected override Expression VisitMember(MemberExpression node)
var matchingMember = typeof(TTo).GetProperty(node.Member.Name);
return Expression.Property(this.Visit(node.Expression), matchingMember);