热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在EntityFrameworkCore使用DataSeeding?(PostgreSQL)

當使用CodeFirst與Migration後,下一步就是DataSeeding,讓我們對table新增基本的資料。在EFCore2.0,DataSeeding只能自己手動處理,在


當使用 Code First 與 Migration 後,下一步就是 Data Seeding,讓我們對 table 新增基本的資料。在 EF Core 2.0,Data Seeding 只能自己手動處理,在 EF Core 2.1 正式提供 Data Seeding。


Version


macOS High Sierra 10.13.4


Docker for Mac 18.03-ce-mac65 (24312)


.NET Core 2.1


Entity Framework 2.1


PostgreSQL 10.3


Npgsql EF Core Provider 2.1


VS Code 1.24.0


DataGrip 2018.4


建立資料


我們可以將一些 database 預設的資料寫在 DbContext.OnModelCreating() ,這樣在 Migration 時,就會順便將資料寫進 database。 1 1 本文為 如何在 Entity Framework Core 使用 Migration ? (PostgreSQL) 內容之延續,請搭配參考


EFLabDbContext.cs




using Microsoft.EntityFrameworkCore;
namespace EFCoreMigration
{
public class EFLabDbContext: DbContext
{
public DbSet Customers { get; set; }
private const string DbCOnnectionString= "Host=localhost;Port=5432;Database=eflab;Username=admin;Password=12345";
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(DbConnectionString);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().HasData(new Customer {
Name = "Sam",
Age = 18,
});

modelBuilder.Entity().HasData(new Customer {
Name = "Kevin",
Age = 19,
});
}
}
}



15 行




protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity().HasData(new Customer {
Name = "Sam",
Age = 18,
});

modelBuilder.Entity().HasData(new Customer {
Name = "Kevin",
Age = 19,
});
}



如同設定 connection string 要 override OnConfiguring() ,若要使用 Data Seeding 則要 override OnModelCreating()


使用 modelBuilder.Entity().HasData() 新增資料,其中 為要新增的 Entity 型別。


因為 CustomerID 為 PK,PostgreSQL 會自動處理,所以我們就不特別指定,只設定 NameAge 兩個欄位。



建立 Migration




~/EFCoreMigration $ dotnet ef migrations add Migration02



因為我們對 DbContext 做了變動,所以要重新建立 Migration。


輸入 dotnet ef migrations add 建立新的 Migration。




  1. 建立 Migration 出現錯誤,EF Core 抱怨 CustomerID 沒有提供。


這目前在 .NET Core 2.1 為 Known Issue ,當使用 modelBuilder.Entity().HasData() 做 Data Seeding 時,目前連 PK 這種 auto-generated 欄位,也必須手動提供。


EFLabDbContext.cs




using Microsoft.EntityFrameworkCore;
namespace EFCoreMigration
{
public class EFLabDbContext: DbContext
{
public DbSet Customers { get; set; }
private const string DbCOnnectionString= "Host=localhost;Port=5432;Database=eflab;Username=admin;Password=12345";
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(DbConnectionString);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var customerID = 1;

modelBuilder.Entity().HasData(new Customer {
CustomerID = customerID++,
Name = "Sam",
Age = 18,
});

modelBuilder.Entity().HasData(new Customer {
CustomerID = customerID++,
Name = "Kevin",
Age = 19,
});
}
}
}



15 行




protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var customerID = 1;

modelBuilder.Entity().HasData(new Customer {
CustomerID = customerID++,
Name = "Sam",
Age = 18,
});

modelBuilder.Entity().HasData(new Customer {
CustomerID = customerID++,
Name = "Kevin",
Age = 19,
});
}



將 PK 的 CustomerID 加入,並自行使用 customerID++ 處理。





~/EFCoreMigration $ dotnet ef migrations add Migration02



再重新建立一次 Migration,這次就成功了。



Migration02.cs



觀察 Migration02.Up() ,發現我們剛剛使用 modelBuilder.Entity().HasData() 新增的資料,已經成為 Migration 的一部分。


ModelSnapshot.cs



觀察 ModelSnapshot.cs ,發現我們剛剛使用 modelBuilder.Entity().HasData() 新增的資料也寫入了 ModelSnapshot.cs ,因此之後再建立新的 Migration 時,就有了 golden sample 可以比對,不會重複新增 Data Seeding 資料。


執行 Migration




~/EFCoreMigration $ dotnet ef database update



輸入 dotnet ef database update 執行 Migration。




  1. 只執行了 Migration02


確認資料




  • 兩筆資料已經透過 Data Seeding 新增至 database


Conclusion



  • 理論上在 Data Seeding 時,PK 欄位應該要省略,但目前 EF Core 2.1 的 HasData() 仍必須自己處理 PK 欄位,是比較可惜的地方

  • Data Seeding 最大的用處在於使用 Docker 的 整合測試 ,當一個測試案例執行時,PostgreSQL 隨著 docker-compose up -d 而跑起來,此時 database 是空的,必須重新執行 Migration 與 Data Seeding,將 schema 與基本資料建立起來,然後才能讓每個測試案例新增測試資料跑測試

  • Data Seeding 也可以用在 production 環境,當 production 環境需要一些基本資料才能正常執行時,就適合使用 Data Seeding


Sample Code


完整的範例可以在我的 GitHub 上找到


Reference


Microsoft Docs , Data Seeding


Entity Framework Core , Seeding data: The seed entity for entity type ‘X’ cannot be added because there was no value provided for the required property ‘Id’.




推荐阅读
author-avatar
灰色头像6888
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有