Author : HASSAN MD TAREQ

Enum support in EF Core

public enum Region : byte
{
	[Description("Asia")]
	Asia = 1,
	[Description("Australia")]
	Australia = 2,
	[Description("Africa")]
	Africa = 3,
	[Description("America")]
	America = 4,
	[Description("Europe")]
	Europe = 5
}

public class Employee
{
    public int Id { get; set; }
	
	// ... ... ...
	
    public Region EmployedRegion { get; set; }
}

EmployeeDbContext.OnModelCreating(...)

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Employee>()
        .Property(e => e.EmployedRegion)
        .HasConversion(
            v => v.ToString(),
            v => (Region)Enum.Parse(typeof(Region), v));
}

Enum in Database First Approach

  • Database column: use nvarchar(n) as column type
  • UI Model property: use Enum type
  • Domain Model <-> UI Model: use AutoMapper to map domain model to/from UI model
  • Disadvantage: if data in changed in master table, enum members must be changed accordingly

Explicitly using ValueConverter

EmployeeDbContext.OnModelCreating(...)

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	var converter = new ValueConverter<Region, string>(
		v => v.ToString(),
		v => (Region)Enum.Parse(typeof(Region), v));

	modelBuilder
		.Entity<Employee>()
		.Property(e => e.EmployedRegion)
		.HasConversion(converter);
}

Using Built-in converters

EmployeeDbContext.OnModelCreating(...)

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	var converter = new EnumToStringConverter<Region>();

	modelBuilder
		.Entity<Employee>()
		.Property(e => e.EmployedRegion)
		.HasConversion(converter);
}

When using built-in-converters, no need to specify the converter explicitly. So, the above can be simplified as below:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{

	modelBuilder
		.Entity<Employee>()
		.Property(e => e.EmployedRegion)
		.HasConversion<string>();
}

The same thing can be achieved by explicitly specifying the column type

public class Employee
{
    public int Id { get; set; }
	
	// ... ... ...
	
    [Column(TypeName = "nvarchar(24)")]
    public Region EmployedRegion { get; set; }
}