简体   繁体   中英

Transition EF Core 3.1 to storing string enum values, rather than ints

I'd like to know if there is an elegant solution to the problem of an existing database that stores enum values as ints, but wanting to transition to storing strings for new records, but leave the ints alone in old records. Naturally, we can make the column types from int to string, and "2" meaning "Ready" can still be stored in a string column..

Is there a technique that allows EF to parse either "2" or "Ready" to that Status.Ready in enum Status { Ready = 2 } ? I know that EF Core has an EnumStringConverter that can understand "Ready" -> Status.Ready but is there a way of extending or customizing it so that it tries to parse the db value both ways? ("Ready" as enum element name -> success, "2" as enum element name -> fail, "2" as enum element value -> success) Would we write a conversion process that eg examined if all the characters in the db value were numeric and hence parse it as a value, else parse it as a name?

Or do people who switch from using ints to using strings also write a massive migration to UPDATE every value in every enum'd column so that all the existing "2" become "Ready"?

You could use a custom converter , like the following

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<MyEntity>()
        .Property(e => e.MyStatusColumn)
        .HasConversion(
            v => v.ToString(),
            v => int.TryParse(v, out int val) ? 
                 (Status)val : 
                 (Status)Enum.Parse(typeof(Status), v)
        );
}

From my own practice, I store enum values as int in the database. For presentation purposes in the client side, I do the following trick.

In the entity class that has your enum property, Status, create another property that gets string value of that enum:

 public enum Status
 {
    None,
    Ready,
    InProcess,
    NotReady
 }

 public class Process
 {
    public int Id { get; set; }
    public Status Status { get; set; }
    public string GetStatus 
    {
        get
        {
            return Status.ToString();
        }
    }
 }

Here, if your Process object has 1 as value of the Status property, the GetStatus property just returns Ready string.

Hope, this answers to your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM