Entity framework 如何在不使用更新数据库的情况下生成启用了迁移的EF6数据库?

Entity framework 如何在不使用更新数据库的情况下生成启用了迁移的EF6数据库?,entity-framework,Entity Framework,在EF5中,我依赖于这样一个事实:我可以使用database.CreateIfNotExists() 我会根据需要生成迁移,但从不将它们签入源代码管理(因为它们往往是开发周期的工件),然后每个开发人员会根据需要从模型中删除并重新创建自己的数据库 然后,我们将通过比较代码的分支来生成迁移,并获得SQL,以应用于生产数据库或其他共享数据库 此工作流似乎不再有效,因为在启用迁移时,如果不先生成所有迁移,然后调用update database,就无法从头生成数据库。由于调用add migration会修

在EF5中,我依赖于这样一个事实:我可以使用
database.CreateIfNotExists()

我会根据需要生成迁移,但从不将它们签入源代码管理(因为它们往往是开发周期的工件),然后每个开发人员会根据需要从模型中删除并重新创建自己的数据库

然后,我们将通过比较代码的分支来生成迁移,并获得SQL,以应用于生产数据库或其他共享数据库

此工作流似乎不再有效,因为在启用迁移时,如果不先生成所有迁移,然后调用update database,就无法从头生成数据库。由于调用add migration会修改csproj文件,这使得我的脚本(允许我们轻松切换分支)无法使用

已为上下文“ApplicationDbContext”启用迁移,但数据库不存在或不包含映射表。使用迁移创建数据库及其表,例如从Package Manager控制台运行“Update database”命令

有没有办法恢复到EF5行为,其中Database.Create将创建数据库的当前版本?

这对我来说很有效(到目前为止……:


我使用CreateDatabaseIfNotExists初始化数据库,能够使用更新数据库并运行我的应用程序,如果数据库不存在,它将创建数据库。这似乎与EF 6.0.x有冲突

我所做的是放弃现有的初始化代码,并用Global.asax中的以下代码替换它

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());
        using (MyContext temp = new MyContext())
        {
            temp.Database.Initialize(true);
        }
编辑:

我升级到EF 6.1,发现它不再有效。()以下是我所做的修复:

    private static readonly Object syncObj = new Object();
    public static bool InitializeDatabase()
    {
        lock (syncObj)
        {
            using (var temp = new MyContext())
            {
                if (temp.Database.Exists()) return true;

                var initializer = new MigrateDatabaseToLatestVersion<MyContext, Configuration>();
                Database.SetInitializer(initializer);
                try
                {
                    temp.Database.Initialize(true);
                    return true;
                }
                catch (Exception ex)
                {
                    //Handle Error in some way
                    return false;
                }
            }
        }
    }
private static readonly Object syncObj=new Object();
公共静态bool InitializeDatabase()
{
锁(同步对象)
{
使用(var temp=new MyContext())
{
if(temp.Database.Exists())返回true;
var initializer=new MigrateDatabaseToLatestVersion();
SetInitializer(初始值设定项);
尝试
{
临时数据库初始化(true);
返回true;
}
捕获(例外情况除外)
{
//以某种方式处理错误
返回false;
}
}
}
}
以下是答案

EF团队分类:这是“设计”的,是我们在EF6中有意进行的更改。如果使用此初始值设定项创建数据库,则会将单个条目添加到_MigrationsHistory表中,该表会使数据库在迁移时不可用(因为这些初始值设定项不使用您的迁移来创建数据库)。在以前的版本中,这让很多人感到困惑,所以我们选择在启用迁移时不自动创建数据库/模式

如果只想应用迁移,可以使用MigrateDatabaseToLatestVersion初始值设定项。如果要删除数据库,则可以轻松地将其包装在自定义初始值设定项中,该初始值设定项包含对context.database.Delete()的调用


其他人被卡住了。我最后在EF6中做了这个

public CatContext(bool forcePreparation)
{
    if (!forcePreparation)
        return;

    if (!Database.Exists() || !Database.CompatibleWithModel(false))
    {
        Database.SetInitializer<CatContext>(new MigrateDatabaseToLatestVersion<CatContext, Configuration>());
    }
    else
    {
        // Database exists and matches the current model.
        // Doing this special thing to avoid the bug that arises sometimes.
        Database.SetInitializer<CatContext>(null);
    }

    Database.Initialize(true);
}

public CatContext()
    : this(forcePreparation: false)
{ }
公共CatContext(布尔力准备)
{
如果(!强制准备)
返回;
如果(!Database.Exists()| |!Database.CompatibleWithModel(false))
{
SetInitializer(新的MigrateDatabaseToLatestVersion());
}
其他的
{
//数据库存在并与当前模型匹配。
//做这个特殊的事情来避免有时出现的错误。
Database.SetInitializer(null);
}
数据库初始化(true);
}
公共CatContext()
:此(forcePreparation:false)
{ }

在我的代码中,我将上下文对象创建为刚刚实现的
new CatContext(true)

,您必须在调用Update()Hi@dannykay1710之前创建一个新的空白数据库:为了精确控制迁移,获取一个挂起迁移的列表,然后仅应用其中的一些…var migrator=new System.Data.Entity.migrations.DbMigrator(config); var pendingMigrations=migrator.GetPendingMigrations();问题是它会将您的数据库从以前的版本迁移到新版本。。。它与CreateDatabaseIfNotExists不完全匹配,CreateDatabaseIfNotExists只在不存在同名数据库时创建最新版本的数据库。当我在数据库中有实际数据时,我希望对迁移进行更精确的控制database@dannykay1710,我不确定我是否明白你的意思,但我想。两个问题。首先,您认为它将迁移到新版本是什么意思?这将运行数据库迁移您是说CreateDatabaseIfNotExists仅在数据库不存在时运行迁移吗?第二,您想要/需要的粒度控制示例是什么?我不喜欢这样的想法,即我编译的应用程序会自动对我的实时数据库进行模式更改,而不会发出任何警告,因为新版本有新的迁移。我只希望在配置的数据库不存在时自动创建模式,而不是在有新迁移时。模式更改很容易导致数据丢失。虽然您可以要求EF在数据丢失时不要进行更改,但在大多数情况下,我仍然希望控件能够测试和控制此更改。@dannykay1710,如果我错了,请更正我。。。如果进行更改需要新的迁移,则在正确运行迁移之前无法测试新代码?(我不记得确切的措辞,但EF将抛出一个模型和DB不匹配的异常)。所以在测试之后的某个时刻,您需要启用迁移或手动更新数据库,对吗?对于数据丢失,您是否有与旧版本EF相同的问题?基于
if (databaseInitialized == false)
    databaseInitialized = MyContext.InitializeDatabase();
    private static readonly Object syncObj = new Object();
    public static bool InitializeDatabase()
    {
        lock (syncObj)
        {
            using (var temp = new MyContext())
            {
                if (temp.Database.Exists()) return true;

                var initializer = new MigrateDatabaseToLatestVersion<MyContext, Configuration>();
                Database.SetInitializer(initializer);
                try
                {
                    temp.Database.Initialize(true);
                    return true;
                }
                catch (Exception ex)
                {
                    //Handle Error in some way
                    return false;
                }
            }
        }
    }
public CatContext(bool forcePreparation)
{
    if (!forcePreparation)
        return;

    if (!Database.Exists() || !Database.CompatibleWithModel(false))
    {
        Database.SetInitializer<CatContext>(new MigrateDatabaseToLatestVersion<CatContext, Configuration>());
    }
    else
    {
        // Database exists and matches the current model.
        // Doing this special thing to avoid the bug that arises sometimes.
        Database.SetInitializer<CatContext>(null);
    }

    Database.Initialize(true);
}

public CatContext()
    : this(forcePreparation: false)
{ }