EF Core Seed data means pre-populating the database with default data. This is useful in scenarios where you want to provide some test data in the development environment. You could use this to set up the application for the first time in a production environment by providing the sample or useful master data.
Source Code:
The source code of this project available in GitHub.
Table of Contents
How to Seed Data in EF Core
In the EF Core, the database seeding has now become part of the Model Configuration. We discussed how to Configure the model using the Fluent API. This is done by overriding the OnModelCreating method.
OnModelCreating
The OnModelCreating method is called by the Context when it initializes the Model for the first time. The Context passes the reference to the ModelBuilder Instance in the OnModelCreating method.
We override the OnModelCreating method, where we get the reference to the Modelbuilder instance. We can use the HasData method of the ModelBuilder to seed the initial data into the database via migrations.
public class EFContext : DbContext
{
private const string connectionString = "Server=(localdb)\\mssqllocaldb;Database=EFCoreDataSeed;Trusted_Connection=True;";
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(connectionString);
}
public DbSet<Department> Department { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Configure domain classes using modelBuilder here
}
} HasData
The HasData method was introduced in EF CoOre 2.1. It is part of the EntityTypeBuilder<T> property of the ModelBuilder API, which we discussed in the Tutorial EF Core Fluent API,
Example of Seeding Data
The following code shows the Example of Seeding Data in EF Core. Consider the Department Model as shown below
public class Department
{
public int DepartmentID { get; set; }
public string Name { get; set; }
}To Seed data in the Department table, First we need to override the OnModelCreating method
Next, we get the reference to the EntityTypeBuilder using the code;
modelBuilder.Entity<Department>()Finally, use the HasData method to supply the list of Departments as shown above
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Department
modelBuilder.Entity<Department>()
.HasData(
new Department { DepartmentID = 1, Name = "HR" },
new Department { DepartmentID = 2, Name = "Admin" },
new Department { DepartmentID = 3, Name = "Production" });
}Once you have added the initial data, you should use migrations to update the database
The ID/Key values must be supplied in HasData method. The EF Core will not generate these when using the HasData method. While inserting the data, the SQL Server will enable the insertion of Identity values. Also do not change the value of the Primary key.
Migrations
Unlike its predecessor entity framework, the EF Core data seeding works with the migrations. Hence we need to create the ef core migration to update the database.
add-migration "v1"and then update the database using update-database or use the script-migration to generate the SQL Script
update-database
or
script-migrationUpdating the Seeded data
You can update the seeded data or add new data later by simply modifying the HasData method. For Example the following code changes the Department name from Production to Development
//Department
modelBuilder.Entity<Department>()
.HasData(
new Department { DepartmentID = 1, Name = "HR" },
new Department { DepartmentID = 2, Name = "Admin" },
new Department { DepartmentID = 3, Name = "Development" }
);Run the add-migration v2 and update-database to update the database with the new department name.
Do not change the value of Primary key i.e DepartmentID. Because EF core uses it to check if any changes made to the record. If the changed field is a Foreign key, then the migration script will delete and recreate all the related records.
Never use some key generator functions for any field. For Example Guid.NewGuid() for a Guid field. DateTime.Now for a DateTime field. This will result in a new migration as the value changes every time you run the add-migration command. Hence always use hardcoded values.
The related data is also added using the HasData method,
The following is the complete example of how to seed the database when various types of relationships are present.
public class Employee
{
[Key]
public int EmployeeID { get; set; }
public string Name { get; set; }
[ForeignKey("Department")]
public int DepartmentID { get; set; }
public virtual Department Department { get; set; }
public virtual EmployeeAddress EmployeeAddress { get; set; }
public virtual ICollection<EmployeesInProject> Projects { get; set; }
}
public class EmployeeAddress
{
[Key, ForeignKey("Employee")]
public int EmployeeID { get; set; }
public string Address { get; set; }
public virtual Employee Employee { get; set; }
}
public class Department
{
public int DepartmentID { get; set; }
public string Name { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
}
public class Project
{
public int ProjectID { get; set; }
public string Name { get; set; }
public virtual ICollection<EmployeesInProject> Employees { get; set; }
}
public class EmployeesInProject
{
public int EmployeeID { get; set; }
public int ProjectID { get; set; }
[ForeignKey("EmployeeID")]
public Employee Employee { get; set; }
[ForeignKey("ProjectID")]
public Project Project { get; set; }
}protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Configure domain classes using modelBuilder here
modelBuilder.Entity<EmployeesInProject>()
.HasKey(e => new { e.EmployeeID, e.ProjectID });
modelBuilder.Entity<Department>()
.HasData(
new Department { DepartmentID = 1, Name = "HR" },
new Department { DepartmentID = 2, Name = "Admin" },
new Department { DepartmentID = 3, Name = "Development" }
);
modelBuilder.Entity<Project>()
.HasData(
new Project { ProjectID = 1, Name = "Cricket" },
new Project { ProjectID = 2, Name = "Politics" },
new Project { ProjectID = 3, Name = "Boxing" },
new Project { ProjectID = 4, Name = "Racing" },
new Project { ProjectID = 5, Name = "Football" },
new Project { ProjectID = 6, Name = "Tennis" }
);
modelBuilder.Entity<Employee>()
.HasData(
new Employee { EmployeeID = 1, Name = "Rahul Dravid", DepartmentID =1 },
new Employee { EmployeeID = 2, Name = "Trump", DepartmentID = 1 },
new Employee { EmployeeID = 3, Name = "Barak Obama", DepartmentID = 2 },
new Employee { EmployeeID = 4, Name = "Virat Kohli", DepartmentID = 2 },
new Employee { EmployeeID = 5, Name = "Muhammad Ali", DepartmentID = 3 },
new Employee { EmployeeID = 6, Name = "Michael Schumacher", DepartmentID = 3 },
new Employee { EmployeeID = 7, Name = "Lionel Messi", DepartmentID = 2 },
new Employee { EmployeeID = 8, Name = "Rafael Nadal", DepartmentID = 3 }
);
modelBuilder.Entity<EmployeeAddress>()
.HasData(
new EmployeeAddress { EmployeeID = 1, Address = "Bangalore, India" },
new EmployeeAddress { EmployeeID = 2, Address = "Newyork, USA" },
new EmployeeAddress { EmployeeID = 3, Address = "California, USA" },
new EmployeeAddress { EmployeeID = 4, Address = "NewDelhi, India" },
new EmployeeAddress { EmployeeID = 5, Address = "Kentuki, USA" },
new EmployeeAddress { EmployeeID = 6, Address = "Hurth, Germany" },
new EmployeeAddress { EmployeeID = 7, Address = "Rosario, Argentina" },
new EmployeeAddress { EmployeeID = 8, Address = "Manacor, Spain" }
);
modelBuilder.Entity<EmployeesInProject>()
.HasData(
new EmployeesInProject { EmployeeID = 1, ProjectID = 1 },
new EmployeesInProject { EmployeeID = 1, ProjectID = 4 },
new EmployeesInProject { EmployeeID = 2, ProjectID = 2 },
new EmployeesInProject { EmployeeID = 2, ProjectID = 3 },
new EmployeesInProject { EmployeeID = 3, ProjectID = 2 },
new EmployeesInProject { EmployeeID = 3, ProjectID = 5 },
new EmployeesInProject { EmployeeID = 4, ProjectID = 1 },
new EmployeesInProject { EmployeeID = 4, ProjectID = 3 },
new EmployeesInProject { EmployeeID = 5, ProjectID = 3 },
new EmployeesInProject { EmployeeID = 5, ProjectID = 2 },
new EmployeesInProject { EmployeeID = 6, ProjectID = 4 },
new EmployeesInProject { EmployeeID = 6, ProjectID = 2 },
new EmployeesInProject { EmployeeID = 7, ProjectID = 5 },
new EmployeesInProject { EmployeeID = 7, ProjectID = 1 },
new EmployeesInProject { EmployeeID = 8, ProjectID = 6 },
new EmployeesInProject { EmployeeID = 8, ProjectID = 5 }
);
}Moving Seed Data to Separate File
The seeding method can get bigger and it would be a lot cleaner if we able to move the method to a separate class file. This is done by creating the extension method and calling the method from the OnModelCreating.
Create a class named ModelBuilderExtensions.cs and add the static seed method.
public static class ModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
//Department
modelBuilder.Entity<Department>()
.HasData(
new Department { DepartmentID = 1, Name = "HR" },
new Department { DepartmentID = 2, Name = "Admin" },
new Department { DepartmentID = 3, Name = "Development" }
);
}
}You can then call the Seed method from the OnModelCreating as shown below
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<EmployeesInProject>()
.HasKey(e => new { e.EmployeeID, e.ProjectID });
modelBuilder.Seed();
}References
Read More
- EF Core Migrations
- Reverse Engineer Database (Database First)
- EF Core Data Seeding to the Database
- EF Core Script MIgration

Will this work even if the table has an identity coloumn?