测试Entity Framework Core迁移

4
如何使用单元/集成测试来确保在已填充的旧版数据库上正确使用基于代码的迁移,包括任何将数据从一列或表映射到另一列或表的附加代码?
我发现一些以前的答案使用了System.Data.Entity命名空间中的类,但似乎这些类在Entity Framework Core中已过时,并且无法手动控制迁移?
我为自己找到了一个解决方案,我会发布出来,但我欢迎其他更好的解决方案。
1个回答

1

数据库由一个Context类、一个ContextModelSnapshot类、一系列迁移文件以及数据表存储的C#对象来定义。

如果您尚未创建迁移,请将所有这些文件复制到您的测试项目中,并将类别名全部重命名为后缀,例如"MyDataEntity" => "MyDataEntityVersion1"。相应地编辑捆绑在一起的.Design.cs文件。然后,在原始数据库上创建新的迁移。

如果您已经创建了新的迁移但无法回退,则可以手动编辑ContextModelSnapshot文件以还原更改。

这种方法的关键是两个类都指向同一个数据库文件。其中一个期望原始状态,而另一个期望升级状态。

在您的测试案例中,您可以执行以下操作:

[TestInitialize]
public void TestInit()
{
    using (var db = new MyDataContext())
        db.Database.EnsureDeleted(); // reset database before each test
}

[TestMethod]
public void Migrate_Version1_To_Version2_On_Populated_Database()
{
    using (var db = new MyDataContextVersion1())
        db.Database.Migrate(); // create database and apply migrations up through Version 1

    // populate the Version 1 database

    App.InitializeDatabase(); // whatever method you would normally call to read/update the database

    // assert statements to test that the Version 2 database looks like you expect.
}

其中InitializeDatabase()看起来像:

public void InitializeDatabase()
{
    using (var db = new MyDataContext())
    {
        db.Database.Migrate();

        // detect if upgrade needed and set new columns

        db.SaveChanges(); 
    }
}

请注意,这个解决方案在一定程度上受到了使用SQLite的启发,因为SQLite不支持在迁移中删除列。 这使我不敢尝试在迁移中做任何更花哨的事情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接