Using Enum with EF Core
Tags: tutorial, csharp, database
Published: 2023-01-28 15:55:38

## Enumeration types

<blockquote cite="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/enum">
An enumeration type (or enum type) is a value type defined by a set of named constants of the underlying integral numeric type.
</blockquote>

## Basic non EF Core example

We want to know if a date is a weekend, we can use [DayOfWeek](https://learn.microsoft.com/en-us/dotnet/api/system.dayofweek?view=net-7.0) enum.

Helper extension

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

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

```csharp
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}");
}
```

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

```

## EF Core example

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

**Figure 1**

![database schema](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5p7ub2l7knzrfqcq0dr.png)

> **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.

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

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

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

![DbContext partial](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s28fkxw99cue1bse290s.png)

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

```csharp
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();
    }

}
```

Call above method.

```csharp
List<Wine> redWines = WineOperations.GetWinesByType(WineType.Red);
```
### 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](https://learn.microsoft.com/en-us/visualstudio/modeling/code-generation-in-a-build-process?view=vs-2022&tabs=csharp).

> **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.

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

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"}
);
```

## 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](https://github.com/karenpayneoregon/enum-tips/tree/master), run the [project](https://github.com/karenpayneoregon/enum-tips/tree/master/EnumHasConversionSample).

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


![Code results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fcoo7x54xj1fyhmfojp2.png)

## Requires

- Microsoft Visual Studio 2022 or higher version 17.4.x