2

我从 EF 和 MVC 开始,并且遵循不同的教程提供了不同的令人困惑的想法,即在我的数据库中放置虚拟测试数据的正确位置是哪里。

所以我做了一些 POCO 类,我有一个 BlahContext

public class BlahContext : DbContext
{
    public DbSet<Blah> Blahs { get; set; }

    public BlahContext() : base("DefaultConnection")
    {
        Configuration.ProxyCreationEnabled = false;
    }
}

然后在 Global.asax.cs 我像这样初始化数据库:

protected void Application_Start()
{
    Database.SetInitializer(new DropCreateDatabaseAlways<BlahContext>());
}

现在我在包管理器控制台中做了以下事情:

PM>  enable-migrations -contexttypename Blah.Models.BlahContext
PM>  add-migration Initial
PM>  update-database

这创建了 Configuration.cs,并且在该类中有一个 Seed() 方法 - 生成的注释暗示这是放置种子数据的正确位置。所以我这样填写:

internal sealed class Configuration : DbMigrationsConfiguration<Blah.Models.BlahContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(Blah.Models.BlahContext context)
    {
#if DEBUG
        context.Blahs.AddOrUpdate(b => b.ID,
            new Blah() { ID = 1, Name = "bum", },
            new Blah() { ID = 2, Name = "moo", }
        );
#endif
    }
}

现在,当我update-database再次运行时,它会在 Blah 表中填充 2 条记录“bum”和“moo”。都好。

但是当我运行应用程序时,似乎Database.SetInitializer()调用Application_Start会导致重新创建数据库,但这次没有调用该Configuration.Seed()方法。所以数据不再存在。

我看到了其他一些创建类的教程,例如:

class BlahContextInitializer : DropCreateDatabaseAlways<BlahContext>

然后 Application_Start 看起来像:

protected void Application_Start()
{
    Database.SetInitializer(new BlahContextInitializer());
}

然后在BlahContextInitializer.Seed()包含虚拟数据的方法中。此策略仅适用于 EF4.1 吗?

我应该将我的种子数据放在 EF5 中的哪个位置,以便在应用程序启动时它不会被清除?

4

3 回答 3

2

但是当我运行应用程序时,似乎 Application_Start 中的 Database.SetInitializer() 调用会导致重新创建数据库,但这次没有调用 Configuration.Seed() 方法。所以数据不再存在。

MigrateDatabaseToLatestVersion如果您使用迁移,则应该使用初始化程序。
或者一起跳过初始化程序 - 如果您计划手动迁移 Db(使用Update-Database)。

问题是您two different initializers(或准确地说是初始化场景)试图一起工作。那有完全不同的“计划”。这是任何其他问题,但尤其是DropCreateDatabaseAlways无法工作的问题。

请记住,Migration Seed 在每次启动应用程序时都会运行,因此它有点不同(与“典型”种子相比)。


如果你有一些复杂的场景(这真的需要你有一个典型的'种子'和你的初始化程序(就像以前做过的那样)——那么请参阅我的这篇关于如何创建这样的自定义初始化程序的帖子......

EF 中 IDatabaseInitializer 的正确用法是什么?

如何创建初始化程序来创建和迁移 mysql 数据库?

于 2013-05-15T01:59:26.160 回答
1

感谢@NSGaga,这就是我最终得到的结果:

protected void Application_Start()
{
    Database.SetInitializer(
        new MigrateDatabaseToLatestVersion<BlahContext, Blah.Migrations.Configuration>()
    );
}

这都会更新数据库,然后按预期调用 Configuration.Seed()。

现在如果我改变我的模型,我仍然需要运行add-migration SomeChange,但我不需要再为之烦恼update-database了。每当我运行应用程序时,它都会自动更新数据库。

另外因为它是迁移而不是重新创建数据库,它不会清除那里的任何额外数据,因此它可以用于生产数据库(这是我使用 EF CF 的另一个担忧)

于 2013-05-16T23:11:44.053 回答
0

您可以将种子数据放在“BlahContextInitializer”中。您已将其设置为在构建时删除并重新创建数据库,因此这将删除所有数据,然后将其重新插入表中。如果您希望它在最初播种数据后将其播种一次,请将 DropCreateDatabaseAlways 更改为不同的设置或从 global.asax 中注释掉初始化程序。

于 2013-05-14T22:14:16.240 回答