Efcore: Value Conversion from Enum to string different from enum value

Created on 25 Feb 2019  路  3Comments  路  Source: dotnet/efcore

In a read only database, I've an entity object with an Enum property that is mapped to a VARCHAR DB column. The problem is that the string value IS NOT equivalent to the Enum .ToString() value, so how am I supposed to write the necessary custom conversion code?

Entity

public class PhaseArticle
{
    public int Id { get; set; }
    public string Code { get; set; }
    public string Description { get; set; }
    public string UnitOfMeasure { get; set; }
    public string Category { get; set; }
    public string Group { get; set; }
    public ArticleFamily Family { get; set; } // --> Enum value
    public double UnitCost { get; set; }
    public string AdditionalDescription { get; set; }
    public string ExternalCode { get; set; }
    public string ColorCode { get; set; }
    public string Note { get; set; }
}

Now I'm using a static helper class with this simple method:

public static class PhaseHelper
{
    public static ArticleFamily GetArticleFamilyFromString(string family)
    {
        switch (family)
        {
            case "CEL":
                return ArticleFamily.Cell;
            case "STR":
                return ArticleFamily.String;
            case "RAW":
                return ArticleFamily.OtherRawMaterial;
            case "SFP":
                return ArticleFamily.SemiFinishedPanel;
            case "FP":
                return ArticleFamily.FinishedPanel;
            default:
                return ArticleFamily.Other;
        }
    }
}

Custom conversion code

public static void ApplyPhaseConversions<T>(this ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<PhaseArticle>()
        .Property(e => e.Family)
        .HasConversion<?>(
            v => 
            { ? },
            v => 
            { ? });
}

Technical details

EF Core version: Microsoft.EntityFrameworkCore v2.1.4
Database Provider: Microsoft.EntityFrameworkCore.SqlServer v2.1.4
Operating system: Windows 10
IDE: Visual Studio 2017 v15.9.6

closed-question customer-reported

All 3 comments

Inverse of the GetArticleFamilyFromString can easily do it. Your input parameter would be enum value and put switch statement on it and return appropriate string value for each enum value.

I'm trying but I'm not able to make it compile.

image

It's complaining about:

Cannot convert Lambda expression into a tree of expressions.

@OculiViridi This is because of limitations in the C# compiler such that it can't create expression trees for this code. The solution is to factory the conversion code into methods and then call those in HasConversion. For example:
```C#
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity()
.Property(e => e.Family)
.HasConversion(
v => FromEnum(v),
v => FromString(v));
}

private static string FromEnum(ArticleFamily family)
{
// Convert code here...
}

private static ArticleFamily FromString(string family)
{
// Convert code here...
}
```
This allows the compiler to create expression trees for the method calls, which in this case is what you want.

Was this page helpful?
0 / 5 - 0 ratings