如何播种EF Core 2.1数据而不将这些数据始终存储在内存中

时间:2018-09-21 15:26:56

标签: c# entity-framework ef-core-2.1

Visual Studio 2017版本15.8.4

.NET Core 2.1

Microsoft.EntityFrameworkCore 2.1.3

根据我已阅读的指南,data seeding是我用来生成插入数据迁移的方法。 EntityTypeBuilder.HasData是用于确保迁移包含用于插入数据的代码的方法,而DbContext.OnModelCreating是确保执行迁移的时间。

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

那不是问题。我可以轻松查找该文件,如果不存在则返回。但是,此异常引起我注意以下事实:OnModelCreating总是在我第一次在应用程序域中实例化派生的DbContext类时被调用,这意味着即使我没有,整个表也将存在于内存中并没有查询数据库的内容,这似乎违反了建立数据库的目的。

因此,我可以删除读取该文件的OnModelCreating中的代码(突然我的测试通过),但是如果这样做,则下次添加迁移时,Migration.Up中的代码将清除掉该表的内容。除非我为在ModelSnapshot中生成的此表擦除EntityTypeBuilder.HasData调用,否则这似乎是一个非常肮脏的hack,并且在将来要更改任何类似的一系列hack之前,我必须手动撤消该调用该表的内容。

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

1 个答案:

答案 0 :(得分:0)

如果我对您的理解正确,那么您想在保存种子数据之后将DbContext重置为其初始状态(不包括任何跟踪的实体)。如果是这样,请分离DbContext跟踪的所有实体:

foreach( var entry in this.ChangeTracker.Entries() )
{
    entry.State = EntityState.Detatched;
}

编辑:

要发表评论,种子数据仅用于迁移。如果您可以为迁移使用不同的DbContext,请从当前DbContext派生另一个DbContext以用于迁移,并且仅将种子数据包括在该DbContext中。 / p>