如何在内存中没有数据的情况下播种 EF Core 2.1 数据

How to seed EF Core 2.1 data without that data always in memory

Visual Studio 2017 版本 15.8.4

.NET 核心 2.1

Microsoft.EntityFrameworkCore 2.1.3

根据我读到的指导,data seeding is the method I should use to generate a migration that inserts data. EntityTypeBuilder.HasData is the method to use to ensure the migration contains the code to insert the data, and DbContext.OnModelCreating是时候去做了。

我有一个很大的 table 我正在从 DbContext.OnModelCreating 中的文件中填充。我还有一个 NUnit 测试项目,其中包含一个执行接触数据库的代码的集成测试。该测试当前失败,因为实例化我派生的 DbContext 会导致调用 OnModelCreating,它会尝试打开我的大文件并将其导入。由于我的测试项目正在创建我的执行上下文,我的数据文件的相对路径不同,所以它找不到该文件并抛出异常。

这不是问题所在。如果文件不存在,我可以轻松地查找文件和 return。但是这个异常让我注意到 OnModelCreating 总是会在我第一次在应用程序域中实例化派生的 DbContext class 时被调用,这意味着整个 table 都在进行存在于内存中,即使我没有查询数据库的内容,这似乎违背了拥有数据库的目的。

所以,我可以删除 OnModelCreating 中读取此文件的代码(突然间我的测试通过了),但如果我这样做,下次我添加迁移时,Migration.Up 中的代码将清除 table 的内容。除非我删除在 ModelSnapshot 中生成的这个 table 的 EntityTypeBuilder.HasData 调用,这看起来像是一个非常肮脏的 hack,并且我必须在将来执行类似系列的肮脏 hack 之前手动撤消它任何时候我想更改此 table.

的内容

因此,问题是,如何在实例化 DbContext 时不将数据自动加载到内存中且不手动编辑 ModelSnapshot 的情况下为迁移提供种子数据?

如果我没理解错的话,您想在保存种子数据后将 DbContext 重置为初始状态(w/o 任何被跟踪的实体)。如果是这样,请分离 DbContext:

跟踪的所有实体
foreach( var entry in this.ChangeTracker.Entries() )
{
    entry.State = EntityState.Detatched;
}

编辑:

为了解决评论,只有迁移需要种子数据。如果您可以为您的迁移使用不同的 DbContext,请从您当前的 DbContext 派生另一个 DbContext 用于您的迁移,并且仅在该 DbContext 中包含种子数据。