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




推荐阅读
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
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社区 版权所有