热门标签 | 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’.




推荐阅读
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
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社区 版权所有