Skip to content

Instantly share code, notes, and snippets.

@lasandell
Last active August 3, 2018 15:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lasandell/5279324 to your computer and use it in GitHub Desktop.
Save lasandell/5279324 to your computer and use it in GitHub Desktop.
Code example to accompany my answer to this stackoverflow question: http://stackoverflow.com/questions/7424501/automapper-for-funcs-between-selector-types/7425211
using AutoMapper;
using System;
using System.Linq;
using System.Linq.Expressions;
namespace MappingTest
{
class Cat
{
public string Name { get; set; }
}
class Dog
{
public string Name { get; set; }
}
class TestMapping
{
static void Main()
{
var dogs = new[]
{
new Dog { Name = "Fido" },
new Dog { Name = "Bella" }
};
var cats = new[]
{
new Cat { Name = "Bella" },
new Cat { Name = "Fluffy" }
};
Mapper.CreateMap<Cat, Dog>();
Expression<Func<Dog, bool>> isDogNamedBella =
dog => dog.Name == "Bella";
var isCatNamedBella = GetMappedSelector(isDogNamedBella);
var catsNamedBella = cats.AsQueryable().Where(isCatNamedBella);
foreach (Cat cat in catsNamedBella)
{
Console.WriteLine("Matching cat: {0}", cat.Name);
}
Console.ReadKey();
}
static Expression<Func<Cat, bool>> GetMappedSelector(Expression<Func<Dog, bool>> selector)
{
Expression<Func<Cat, Dog>> mapper = Mapper.CreateMapExpression<Cat, Dog>();
Expression<Func<Cat, bool>> mappedSelector = selector.Compose(mapper);
return mappedSelector;
}
}
public static class FunctionCompositionExtensions
{
public static Expression<Func<X, Y>> Compose<X, Y, Z>(this Expression<Func<Z, Y>> outer, Expression<Func<X, Z>> inner)
{
return Expression.Lambda<Func<X ,Y>>(
ParameterReplacer.Replace(outer.Body, outer.Parameters[0], inner.Body),
inner.Parameters[0]);
}
}
class ParameterReplacer : ExpressionVisitor
{
private ParameterExpression _parameter;
private Expression _replacement;
private ParameterReplacer(ParameterExpression parameter, Expression replacement)
{
_parameter = parameter;
_replacement = replacement;
}
public static Expression Replace(Expression expression, ParameterExpression parameter, Expression replacement)
{
return new ParameterReplacer(parameter, replacement).Visit(expression);
}
protected override Expression VisitParameter(ParameterExpression parameter)
{
if (parameter == _parameter)
{
return _replacement;
}
return base.VisitParameter(parameter);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment