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




推荐阅读
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
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社区 版权所有