实体框架5迁移:设置数据库的初始迁移和单个种子 [英] Entity Framework 5 Migrations: Setting up an initial migration and single seed of the database

查看:136
本文介绍了实体框架5迁移:设置数据库的初始迁移和单个种子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MVC4应用程序,我最近升级到实体框架5,我试图将我们的数据库移植到使用从删除和创建每个运行的开发风格的迁移。



这是我在应用程序启动功能中所做的一切。

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

我运行在我的仓库项目中启用迁移命令,我认为这将创建一个初始迁移文件,但创建的唯一文件是配置



当我删除数据库时,它首先通过代码创建它,并从配置文件中创建数据库。在配置文件中,我将所有 Add()函数更改为 AddOrUpdate()



但是,每当网站启动并重复所有种子数据时,它会在我的配置文件中运行种子功能。



我想象,它将创建一个初始迁移文件,因为我看到的博客建议我可以把种子数据放在在那里,但是它没有



任何人都可以解释我应该如何设置代码中的数据块,以便它只能种子一次?






LINK:我跟踪的迁移博客帖子






虽然这是非常有趣的使用EF migrate.exe我已经切换到使用 roundhouse for runn迁移。我仍然使用EF支持我的迁移基于模型,但我写了一个小控制台应用程序将迁移写入SQL文件。然后,我使用roundhouse通过我的rake构建脚本自己执行迁移。有一点更多的过程涉及,但是比应用程序启动时使用EF执行迁移更加稳定。

解决方案

p>这被证明是一个流行的帖子,所以我已经根据他人的反馈更新了。要知道的主要事情是,配置类中的Seed方法是在应用程序启动时运行的,这不是模板方法中的注释所暗示的。请参阅Microsoft的某人的答案。此帖子关于为什么 - 感谢Jason Learmouth发现。



如果像我一样,只想运行数据库更新,如果有任何待处理那么迁移就需要做更多的工作。如果通过调用migrator.GetPendingMigrations()有待处理的迁移,您可以找到这一点,但是您必须在ctor中执行此操作,因为在调用Seed方法之前清除挂起的迁移列表。实现这一点的代码在Migrations.Configuration类中如下所示:

 内部密封类配置:DbMigrationsConfiguration< YourDbContext> ; 
{
private readonly bool _pendingMigrations;

public配置()
{
//如果要自动迁移,请将下面的行删除注释。
// AutomaticMigrationsEnabled = true;
var migrator = new DbMigrator(this);
_pendingMigrations = migrator.GetPendingMigrations()。Any();
}

protected override void Seed(MyDbContext context)
{
// Microsoft评论说迁移到最新版本后将调用此方法。
//但是我的测试显示,每次软件启动时都会调用

//如果没有任何待处理的迁移
if(!_pendingMigrations)返回,则退出;

//否则运行你的代码来种子数据库,例如
context.Foos.AddOrUpdate(new Foo {bar = true});
}
}

我应该指出,有些人建议把种子代码在实际的向上迁移代码中。这是有效的,但是意味着你需要记住将种子代码放在每个新的迁移中,并且它很难记住,所以我不会这样做。但是,如果您的种子随每次迁移发生变化,那么这可能是一个很好的方式。


I have an MVC4 app which I've recently upgraded to Entity Framework 5 and I am trying to move our database over to using migrations from the development style of dropping and creating each run.

Here's what I've done in my app start function.

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

I ran the Enable-Migrations command on my repositories project and I thought that this would create an initial migration file however the only file it created was Configuration

When I delete the database it creates it as expected via code first and seeds the database from the Configuration file. In the configuration file I changed all the Add() functions to AddOrUpdate()

However it runs the seed function in my Configuration file each time the website starts and duplicates all the seed data again and again.

I imagined that it would create an initial migration file as the blog I read suggested that it would and I could put the seed data in there but it didn't

Can anyone explain how I should be setting up DB in code so that it only seeds once?


LINK: The migrations blog post I followed


While this is quite interesting for using the EF migrate.exe I've since switched to using roundhouse for running migrations. I still use EF to scaffold my migrations based on the models but I wrote a little console app to write the migrations out to SQL files. I then use roundhouse to perform the migrations themselves through my rake build scripts. There's a little more process involved but it's much more stable than using EF to perform the migrations on the fly when the application starts up.

解决方案

This has proved to be a popular post so I have updated it in light of feedback from others. The main thing to know is that the Seed method in the Configuration class is run EVERY time the application starts, which isn't what the comment in the template method implies. See the answer from someone at Microsoft to this post about why that is - thanks to Jason Learmouth for finding that.

If you, like me, only want to run the database updates if there are any pending migrations then you need to do a bit more work. You can find that out if there are pending migrations by calling migrator.GetPendingMigrations(), but you have to do that in the ctor as the list of pending migrations is cleared before Seed method is called. The code to implement this, which goes in the Migrations.Configuration class is as follows:

internal sealed class Configuration : DbMigrationsConfiguration<YourDbContext>
{ 
    private readonly bool _pendingMigrations;

    public Configuration()
    {
        // If you want automatic migrations the uncomment the line below.
        //AutomaticMigrationsEnabled = true;
        var migrator = new DbMigrator(this);
        _pendingMigrations = migrator.GetPendingMigrations().Any();
    }

    protected override void Seed(MyDbContext context)
    {
        //Microsoft comment says "This method will be called after migrating to the latest version."
        //However my testing shows that it is called every time the software starts

        //Exit if there aren't any pending migrations
        if (!_pendingMigrations) return;

        //else run your code to seed the database, e.g.
        context.Foos.AddOrUpdate( new Foo { bar = true});
    }
}

I should point out that some people have suggested putting the seed code in the actual 'up' migration code. This works, but means you need to remember to put the seed code in each new migration and its pretty hard remember so I wouldn't do that. However if your seed changes with each migration then that might be the a good way to go.

这篇关于实体框架5迁移:设置数据库的初始迁移和单个种子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆