I have a business logic object User
with ValueObject field UserId
. I need to translate expression tree with User
to similar tree with DbUser
using AutoMapper.
Here is my setup:
public static void Main(string[] args)
{
// create new AutoMapper
var mapperConfiguration = new MapperConfiguration(
cfg =>
{
cfg.CreateMap<UserId, string>().ConvertUsing(u => u.ToString());
cfg.CreateMap<string, UserId>().ConvertUsing(u => UserId.FromString(u));
cfg.CreateMap<User, DbUser>()
.ForMember(dbu => dbu.Id, opt => opt.MapFrom(u => u.Id.ToString()));
cfg.CreateMap<DbUser, User>()
.ForMember(u => u.Id, opt => opt.MapFrom(dbu => UserId.FromString(dbu.Id)));
cfg.AddExpressionMapping();
}
);
mapperConfiguration.AssertConfigurationIsValid();
IMapper mapper = mapperConfiguration.CreateMapper();
// map some expression
var idToFind = new UserId(Guid.NewGuid());
Expression<Func<User, bool>> bllExpression = x => x.Id == idToFind;
var dbExpression = mapper.MapExpression<Expression<Func<DbUser, bool>>>(bllExpression);
Console.WriteLine(dbExpression.ToString());
}
User and DbUser:
public class User
{
public UserId Id { get; set; }
public string Name { get; set; }
}
public class DbUser
{
public string Id { get; set; }
public string Name { get; set; }
}
UserId:
public class UserId
{
public Guid Id { get; }
public UserId(Guid id) => Id = id;
public override string ToString()
{
return Id.ToString();
}
public static UserId FromString(string value)
{
return new UserId(Guid.Parse(value));
}
public static bool operator ==(UserId a, UserId b)
{
return a?.Id == b?.Id;
}
public static bool operator !=(UserId a, UserId b)
{
return a?.Id != b?.Id;
}
}
So, when I convert those expressions I get this result:
x => (FromString(x.Id) == 799e50f4-339f-4207-819e-194bbe206ae2)
But I cannot use this expression as database query e.g. in EntityFramework or MongoDb. Because there is no FromString
function. Instead I need to compare already flattened values, in this case string
:
x => (x.Id == "799e50f4-339f-4207-819e-194bbe206ae2")
How can I get this expression?