Using Enum with EF Core

Karen Payne - Jan 28 '23 - - Dev Community

Enumeration types

An enumeration type (or enum type) is a value type defined by a set of named constants of the underlying integral numeric type.

Basic non EF Core example

We want to know if a date is a weekend, we can use DayOfWeek enum.

Helper extension



internal static class DateOnlyExtensions
{
    public static bool IsWeekend(this DateOnly sender)
        => (sender.DayOfWeek == DayOfWeek.Sunday || 
            sender.DayOfWeek == DayOfWeek.Saturday);
}


Enter fullscreen mode Exit fullscreen mode

Mock-up some dates and check for is a DateOnly a weekend.



var dates = Enumerable
    .Range(1, 17)
    .Select(x => new DateOnly(2023, 1, x)).ToList();

foreach (var date in dates)
{
    Console.WriteLine($"{date,-12:MM/dd/yyyy}" + 
                      $"{date.IsWeekend(),-10}{date.DayOfWeek}");
}


Enter fullscreen mode Exit fullscreen mode

Results



01/01/2023  True      Sunday
01/02/2023  False     Monday
01/03/2023  False     Tuesday
01/04/2023  False     Wednesday
01/05/2023  False     Thursday
01/06/2023  False     Friday
01/07/2023  True      Saturday
01/08/2023  True      Sunday
01/09/2023  False     Monday
01/10/2023  False     Tuesday
01/11/2023  False     Wednesday
01/12/2023  False     Thursday
01/13/2023  False     Friday
01/14/2023  True      Saturday
01/15/2023  True      Sunday
01/16/2023  False     Monday
01/17/2023  False     Tuesday



Enter fullscreen mode Exit fullscreen mode

EF Core example

In this example we want to associate wines with wine types in a SQL-Server database table.

Figure 1

database schema

Note
The table WineType is not used in code, it is for a T4 template discussed later, for now we are only interested in the Wine table.

Wine model where WineType is an enum.



public class Wine
{
    public int WineId { get; set; }
    public string Name { get; set; }
    public WineType WineType { get; set; }
    public override string ToString() => $"{WineType} {Name}";
}


Enter fullscreen mode Exit fullscreen mode

WineType enum



public enum WineType
{
    [Description("Classic red")]
    Red = 1,
    [Description("Dinner white")]
    White = 2,
    [Description("Imported rose")]
    Rose = 3
}


Enter fullscreen mode Exit fullscreen mode

To configure, in the DbContext, OnModelCreating setup an association between WineType to int as follows.

DbContext partial

This allows us to, in this case query for a specific wine type as follows.



namespace EnumHasConversion.Classes;

public class WineOperations
{
    public static List<Wine> GetWinesByType(WineType wineType)
    {
        using var context = new WineContext();
        return context.Wines
            .Where(wine => wine.WineType == wineType)
            .ToList();
    }

}


Enter fullscreen mode Exit fullscreen mode

Call above method.



List<Wine> redWines = WineOperations.GetWinesByType(WineType.Red);


Enter fullscreen mode Exit fullscreen mode

T4 Template

The reason for using a template is for sharing the enum between applications and ensuring members are up to date. This is done by creating a T4 template that reads from a SQL-Server database table which is shown figure 1.

Usually a T4 is updated on change which means if data is modified in the database someone needs to inform the developer and in turn the developer must make a small change to the template or delete the associated .cs file, or automate the process via MS-Build: Invoke text transformation in the build process.

Note
There is a model in the source code which is for ensuring there is a table for the template to work with for demo purposes only.



[Table("WineType")]
public class WineTypes
{
    [Key]
    public int Id { get; set; }
    public string TypeName { get; set; }
    public string  Description { get; set; }
}


Enter fullscreen mode Exit fullscreen mode

In our DbContext OnModelCreating



modelBuilder.Entity<WineTypes>().HasData(
new WineTypes() {Id = 1, TypeName = "Red", Description = "Classic red"},
new WineTypes() {Id = 2, TypeName = "White", Description = "Dinner white"},
new WineTypes() {Id = 3, TypeName = "Rose", Description = "Imported rose"}
);

Enter fullscreen mode Exit fullscreen mode




Summary

Using enums in C# with EF Core is extremely easy and note that the use of a T4 template is completely optional, without a T4 template simply create a regular enum.

Source code

Clone the following GitHub repository, run the project.

The first time running the project the database is created and populated then afterwards data is read.

Code results

Requires

  • Microsoft Visual Studio 2022 or higher version 17.4.x
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .