Skip to content

Issues with enum to string mapping in expressions #145

Closed

Description

@Johkie

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!

Activity

  1. BlaiseD commented on Aug 19, 2022

    @BlaiseD
    Member

    An expression like this or a DbFunction (if one exists) to perform the parse should work - really an EF problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions