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);
}
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}");
}
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
Note
The tableWineType
is not used in code, it is for a T4 template discussed later, for now we are only interested in theWine
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}";
}
WineType enum
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.
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();
}
}
Call above method.
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.
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; }
}
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, run the project.
The first time running the project the database is created and populated then afterwards data is read.
Requires
- Microsoft Visual Studio 2022 or higher version 17.4.x