Correct posture? How to use enum types in EF Core?

Correct posture? How to use enum types in EF Core?

Entities in EntityFramework Core do not directly support operations on enum types, which brings us a lot of trouble during development.

Last updated 11/9/2021 10:06 AM
waitaction
3 min read
Category
EF Core
Tags
.NET C# EF Core ORM .NET Core

EntityFramework Core does not directly support enum types for entities, which causes some trouble during development. Below is a summary of how to use enums in EF Core.

For example, the MsgInfo entity below corresponds to the database table MsgInfo, where the field SendState (send status) has two enum states in business logic: Sent Successfully and Send Failed. However, EF generates it as an int type instead of an enum, and it cannot be modified to an enum because that would cause EF to write and read data abnormally.

Original Entity

public partial class MsgInfo
{
    public string Id { get; set; }
    public string UserAddress { get; set; }
    public string Content { get; set; }
    public int SendState { get; set; }
}

Here, add a new field SendStateEnum set to the enum type, and use [NotMapped] to avoid mapping to the database. To prevent serialization when outputting HTTP, you can also add the [Newtonsoft.Json.JsonIgnore] attribute.

Requires the NuGet package Newtonsoft.Json

The modified entity code is as follows:

Modified Entity

public partial class MsgInfo
{
    public string Id { get; set; }
    public string UserAddress { get; set; }
    public string Content { get; set; }
    public int SendState { get; set; }

    [NotMapped]
    [Newtonsoft.Json.JsonIgnore]
    public SendStateEnum SendStateEnum
    {
        get
        {
            switch (SendState)
            {
                case (int)SendStateEnum.Fail:
                    return SendStateEnum.Fail;
                case (int)SendStateEnum.Success:
                    return SendStateEnum.Success;
                default:
                    return SendStateEnum.UnKnow;
            }
        }
        set
        {
            SendState = (int)value;
        }

    }
}
public enum SendStateEnum
{
    Success = 1,
    Fail = 2,
    UnKnow =3
}

After adding the SendStateEnum field, when using EF Core to operate or read, SendStateEnum replaces the SendState field (Note: The site administrator tested and found a discrepancy with the original text. In the code below from the original text, it seems that SendState should be used for EF Core operations. If you have different opinions, please leave a comment for correction.)

using (var context = new FrameworkDbContext())
{
    var result = context.MsgInfo.Where(m => m.SendStateEnum == SendStateEnum.Success);
}

Of course, to prevent the original SendState field from being used, you can add the [Obsolete] attribute to remind users that the field SendState is deprecated.

Final Modified Entity Code

public partial class MsgInfo
{
    public string Id { get; set; }
    public string UserAddress { get; set; }
    public string Content { get; set; }

    [Obsolete]
    public int SendState { get; set; }

    [NotMapped]
    [Newtonsoft.Json.JsonIgnore]
    public SendStateEnum SendStateEnum
    {
        get
        {
            switch (SendState)
            {
                case (int)SendStateEnum.Fail:
                    return SendStateEnum.Fail;
                case (int)SendStateEnum.Success:
                    return SendStateEnum.Success;
                default:
                    return SendStateEnum.UnKnow;
            }
        }
        set
        {
            SendState = (int)value;
        }
    }
}
public enum SendStateEnum
{
    Success = 1,
    Fail = 2,
    UnKnow =3
}
Keep Exploring

Related Reading

More Articles