问题
如何在.Net项目中初始化数据库的数据?
前置条件
- 基于
.Net 6.0
创建的C#
Demo - 主要目录结构如下
txt
DemoApplication
|---> src
|---> db
|---> DataSeeder.cs
|---> SqlDbContext.cs
|---> configuration folder
|---> BooksEntityConfiguration.cs
|---> Migrations folder
|---> Program.cs
通过代码生成数据库表
0. 类之间的依赖关系
flowchart LR
A0[Books实体类] --> |被使用| M0[BooksEntityConfiguration.cs]
M0 -->|被使用 | A1[SqlDbContext]
A1 -->|被使用 | M2[Program.cs]
1. 生成实体Books类的配置文件
创建BooksEntityConfiguration.cs
类,继承IEntityTypeConfiguration
,参数是Books
类。
然后在Configure
方法里配置Books
数据表的额外属性,如Key是哪个字段,哪个字段什么样是否必须等。 注意这里 ,配置是可以跳过的,那么程序就会按照Books
类的定义生成数据表的结构。
C#
// BooksEntityConfiguration.cs
public class BooksEntityConfiguration : IEntityTypeConfiguration<Books>
{
public void Configure(EntityTypeBuilder<Books> builder)
{
builder.HasKey(b => b.Id);
builder.Property(b => b.Id).HasDefaultValueSql("NEWID()");
builder.Property(b => b.Name).IsRequired();
builder.Property(b => b.AuthorId).IsRequired();
builder.Property(b => b.CreatedBy).HasColumnType("date");
builder.HasIndex(b => b.Name).IsUnique();
}
}
2. 应用Books类的配置
定义SqlDbContext.cs
类,继承DbContext
,在OnModelCreating
方法中应用前面定义的关于Books的配置。
C#
// SqlDbContext.cs
public class SqlDbContext : DbContext
{
public DbSet<Books> Books { get; set; }
public SqlDbContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new BooksEntityConfiguration());
}
}
3. 安装并使用dotnet命令生成Migrations文件
- 安装
dotnet
工具
sh
dotnet tool install --global dotnet-ef
- 使用
dotnet-ef
命令,根据配置文件在Migrations
目录下生成要迁移的数据文件.
sh
dotnet ef migrations add Books --project Demo/Demo.csproj
dotnet ef database update -p Demo/Demo.csproj
4. 基于Migrations文件创建数据库的表
在 Program.cs
获取到DB的实例,然后执行Migrate
方法,执行上一步生成的Migrations文件,在数据库生成需要的数据表。
C#
// Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var db = services.GetService<SqlDbContext>();
// 这里
db.Database.Migrate();
}
初始化数据
0. 类之间的依赖关系
flowchart LR
M1[Program.cs] --> |调用|A[Migrate]
M1 --> |调用| B[Seed]
B --> |调用| B1[DataSeeder]
1. 初始化Books数据
在DataSeeder.cs
静态类中,配置books列表,然后将这些数据更新到数据库的表中,也可以指定哪些字段不需要更新。
C#
// DataSeeder.cs
public static class DataSeeder
{
public static void SeedData(this SqlDbContext db)
{
SeedBooks(db);
}
private static void SeedBooks(SqlDbContext db)
{
var books = new List<Books>
{
new Books { Name = "悉达多", Type = "文学"}
};
db.BulkInsertOrUpdate(books, options =>
{
options.UpdateByProperties = new List<string> { nameof(Books.Name) };
options.PropertiesToExcludeOnUpdate = new List<string> { nameof(Books.Id) };
});
}
2. 执行
在 Program.cs
获取到DB的实例,然后在项目开始的时候,初始化数据库中表的数据。这部分由SeedData
方法来实现。
C#
// Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var db = services.GetService<SqlDbContext>();
db.Database.Migrate();
// 这里
db.SeedData();
}