Enum is a special class that has read-only variables and cannot be changed. The values can be accessed through dot operator. They are supported in Entity Framework staring from version 5.0 onwards. The default data type of enumerated values is Integer, which starts from zero index, and the value gets increased by one. In Entity Framework, it can have the following types:
- Byte
- Int16
- Int32
- Int64
- SByte
Entity Framework Core supports both approaches i.e. Code First and Database First. It is a light-weighted and cross platform technology to access the database.
Support of Enum in Code First
In Entity Framework 4.1, Microsoft introduced Code-First approach for Domain Driven Design application i.e. enables software developers to focus on the domain of an application by creating classes directly rather than designing the database first and creates matching classes.
Enum are supported in EF 5.0. To use enum in Entity Framework, the project must have a minimum version 4.5 of the .NET framework.
Support of Enum in Database First
The Database-First approach is an alternative to the Code-First approach. The design can be created using the designer or by using scripts. EF creates the model classes, DB Context, properties, etc. from the database to create a link between the database and an application.
Example Scenario
Let’s take an example of the patient registration on a portal provided by the hospital. It has three different membership plan listed below:
- Basic
- Silver
- Gold
Each Membership Plan has a discount on hospital services:
- 10% Discount
- 25 % Discount
- 50% Discount
A patient can subscribe to any plan by paying a certain amount using the following payment methods:
- Cash on Delivery
- Credit Card
Membership Plans will use the enum values and it can be used as a Foreign Key in Patient entity.
using System;
namespace MyPatientPortal.Business.Models
{
public class Patient
{
public enum enPaymentMethod
{
CreditCard,
CashOnDelivery
}
public int Id { get; set; } // User for PK
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public string BirthDate { get; set; }
public string EmailAddress { get; set; }
public int ContactNumber { get; set; }
public enPaymentMethod PaymentMethod { get; set; }
public MembershipPlan.Plan MembershipPlan { get; set; }
public MembershipPlan MembershipPlanRelation { get; set; } // User for FK
}
public class MembershipPlan
{
public enum Plan
{
Basic,
Silver,
Gold
}
public enum ServiceDiscount
{
Ten,
TwentyFive,
Fifty
}
public Plan Name { get; set; }
public int AllowedFamilyMember { get; set; }
public int AnnualPrice { get; set; }
public ServiceDiscount Discount { get; set; }
}
}
Enum as Integer
To configure PaymentMethod property as Enum, you need to specify the PaymentMethod property to datatype <int> in Patient entity.
using Microsoft.EntityFrameworkCore;
namespace MyPatientPortal.Business.Models
{
public class PatientDbContext : DbContext
{
public DbSet Patients { get; set; }
public DbSet MembershipPlans { get; set; }
public PatientDbContext (DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder objModelBuilder)
{
objModelBuilder.Entity()
.ToTable("MembershipPlans");
objModelBuilder.Entity()
.ToTable("Patients");
// convert to datatype to store in database
objModelBuilder.Entity()
.Property(c => c.PaymentMethod)
.HasConversion();
base.OnModelCreating(objModelBuilder);
}
}
}
Enum as String
To store Enum as String, use value-conversion in the PatientDBContext Class and the class will look like this:
using Microsoft.EntityFrameworkCore;
namespace MyPatientPortal.Business.Models
{
public class PatientDbContext : DbContext
{
public DbSet Patients { get; set; }
public DbSet MembershipPlans { get; set; }
public PatientDbContext (DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder objModelBuilder)
{
objModelBuilder.Entity()
.ToTable("MembershipPlans");
objModelBuilder.Entity()
.ToTable("Patients");
objModelBuilder.Entity()
.Property(c => c.PaymentMethod)
.HasConversion();
// specify property as datatype to store in database
objModelBuilder.Entity()
.Property(s => s.Discount)
.HasConversion();
base.OnModelCreating(objModelBuilder);
}
}
}
Enum as Primary Key
Primary Key makes the entire record unique in a relational table. To specify the Enum as Primary Key, convert the property datatype to <string> and assign the primary key.
using Microsoft.EntityFrameworkCore;
namespace MyPatientPortal.Business.Models
{
public class PatientDbContext : DbContext
{
public DbSet Patients { get; set; }
public DbSet MembershipPlans { get; set; }
public PatientDbContext (DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder objModelBuilder)
{
objModelBuilder.Entity()
.ToTable("MembershipPlans");
objModelBuilder.Entity()
.ToTable("Patients");
objModelBuilder.Entity()
.Property(c => c.MembershipPlan)
.HasConversion();
objModelBuilder.Entity()
.Property(c => c.PaymentMethod)
.HasConversion();
objModelBuilder.Entity()
.Property(s => s.Discount)
.HasConversion();
//Specify property as to be stored as enum in database
objModelBuilder.Entity()
.Property(s => s.Name)
.HasConversion();
// Specify ‘Name’ as a Primary Key for the MembershipPlan entity
objModelBuilder.Entity()
.HasKey(s => s.Name);
base.OnModelCreating(objModelBuilder);
}
}
}
Enum as Foreign Key
Foreign Key provides a communication between the data in two different tables. It refers to the Primary Key of the other table.
To specify Enum as a Foreign Key, a relational property is added in the entity i.e. MembershipPlanRelation in Patient. This allows you to retrieve the Membership Plan for a Patient and the Patient DbContext class will look like this:
using Microsoft.EntityFrameworkCore;
namespace MyPatientPortal.Business.Models
{
public class PatientDbContext : DbContext
{
public DbSet Patients { get; set; }
public DbSet MembershipPlans { get; set; }
public PatientDbContext (DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder objModelBuilder)
{
objModelBuilder.Entity()
.ToTable("MembershipPlans");
objModelBuilder.Entity()
.ToTable("Patients");
objModelBuilder.Entity()
.Property(c => c.MembershipPlan)
.HasConversion();
objModelBuilder.Entity()
.Property(c => c.PaymentMethod)
.HasConversion();
objModelBuilder.Entity()
.Property(s => s.Discount)
.HasConversion();
objModelBuilder.Entity()
.Property(s => s.Name)
.HasConversion();
objModelBuilder.Entity()
.HasKey(s => s.Name);
// Specify the Foreign Key on the property of Patient.MembershipPlanRelation which is already configured as
objModelBuilder.Entity()
.HasOne(c => c.MembershipPlanRelation)
.WithMany()
.HasForeignKey(c => c.MembershipPlan);
//Configure the Primary Key for the property ‘Id’
objModelBuilder.Entity()
.HasKey(c => c.Id);
// Set the Identity specification on the above Primary Key
objModelBuilder.Entity()
.Property(c => c.Id)
.ValueGeneratedOnAdd();
base.OnModelCreating(objModelBuilder);
}
}
}
In the end, you can add sample data for the membership plans in the database:
objModelBuilder.Entity().HasData(
new MembershipPlan
{
Name = MembershipPlan.Level.Basic,
AllowedFamilyMember = 1,
AnnualPrice = 100,
Discount = MembershipPlan.ServiceDiscount.Ten
},
new MembershipPlan
{
Name = MembershipPlan.Level.Silver,
AllowedFamilyMember = 5,
AnnualPrice = 200,
Discount = MembershipPlan.ServiceDiscount.TwentyFive
},
new MembershipPlan
{
Name = MembershipPlan.Level.Gold,
AllowedFamilyMember = 10,
AnnualPrice = 400,
Discount = MembershipPlan.ServiceDiscount.Fifty
}
);