2

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?

Link to .NET Fiddle

DenisNP
  • 141
  • 1
  • 6
  • You can use ForPath in this case, have a look at this https://dotnetfiddle.net/FzuJXR. However, there is a small change needed in writing the expression, it has to be like `x => x.Id.Id == idToFind.Id`. Hope it helps. – Helmi Khaled Oct 30 '22 at 14:32

0 Answers0