Issues with enum to string mapping in expressions
Johkie opened this issue · 1 comments
Versions
- .NET Core 3.1
-- Automapper: 10.1.1
-- Automapper.Extensions.ExpressionMapping: 4.1.3
-- Microsoft.EntityFrameworkCore: 5.0.10_
Setup
Hi,
I've got the following objects (quite simplified but still)
public enum CountryA3
{
AFG = 0,
ALA = 1,
....
}
public class TestDto
{
public CountryA3 Country { get; set; }
}
public class TestModel
{
public string Country { get; set; }
}
With the following map configuration (works as intended while mapping between plain TestDto <-> TestModel objects)
CreateMap<TestModel, TestDto>()
.ForMember(d => d.Country, opt => opt.MapFrom(s => Enum.Parse<CountryA3>(s.Country)));
CreateMap<TestDto, TestModel>()
.ForMember(d => d.Country, opt => opt.MapFrom(s => s.Country.ToString()));
Issue
I am currently required to save the value of the enum as a string in an SQL database while making the TestDto querable from an API endpoint. The query is translated dynamically in a custom resolver that generates an expression based upon a specified class. In this case the expression is built upon TestDto since the model isn't exposed to the API. The result may looks like this.
Expression<Func<TestDto, bool>> expression = x => (x.Country == AFG)
// x => (x.Country == AFG)
This is where things get complicated, because when I map the expression to the TestModel, I get the following result
var exp = _mapper.Map<Expression<Func<TestModel, bool>>>(expression);
// Result: x => (Parse(x.Country) == AFG)
Automapper itself is happy, but I've ended up with an expression that can't be translated by EFCore in my where clause that generates the following exception.
The LINQ expression 'DbSet<TestModel>()
.Where(s => Enum.Parse<CountryA3>(s.Country) == AFG)' could not be translated.
Additional information: Translation of method 'System.Enum.Parse' failed
Is there any way I can get the mapper to give me a result that is readable for EFCore? Since the expression mapping seems to be using the Model -> Dto mapper in this case, I'm not really sure how to specify that I want to work with string comparing instead of using the enum (like the Dto -> Model map).
I've become quite desperate so any guidance to what I can do would be very much appreciated.
Thanks!
An expression like this or a DbFunction (if one exists) to perform the parse should work - really an EF problem.