如何在不使用update-database的情况下生成启用迁移的EF6数据库?

Dou*_*oug 12 entity-framework

在EF5中,我依赖的事实是我可以使用模型从模型重新创建数据库 Database.CreateIfNotExists()

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

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

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

已为上下文"ApplicationDbContext"启用迁移,但数据库不存在或不包含映射表.使用迁移创建数据库及其表,例如通过从程序包管理器控制台运行"Update-Database"命令.

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

Jef*_*eff 12

我正在使用CreateDatabaseIfNotExists来初始化数据库,并且能够使用update-database并运行我的应用程序,如果数据库尚不存在,它将创建数据库.这似乎与EF 6.0.x有关.

这很有用,但不是我用过的.

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

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>());
        using (MyContext temp = new MyContext())
        {
            temp.Database.Initialize(true);
        }
Run Code Online (Sandbox Code Playgroud)

注意:MyContext是我使用的上下文,Configuration是在启用迁移时创建的配置文件.

我看过很多帖子,人们对此有疑问,但描述解决方案的人并不多.我不确定为什么这么多人,包括我自己,都错过了这个突破性的变化...(如果有某个地方的描述,我从来没有看到它,直到为时已晚.)

编辑:

这是我添加到上下文类的代码.我不喜欢它曾经如何工作,但它现在完成了工作.请参阅@ Doug对OP关于CodePlex投票的评论.

private static readonly Object syncObj = new Object();
public static bool InitializeDatabase()
{
    lock (syncObj)
    {
        using (var temp = new TbdContext())
        {
            ObjectContext oc = null;
            try
            {
                oc = temp.ObjectContext;
            }
            catch (Exception ex)
            {
                //Ignore error
                Console.WriteLine(ex);
            }

            if (oc != null && oc.DatabaseExists())
            {
                return true;
            }
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<TbdContext, Configuration>());
            try
            {
                temp.Database.Initialize(true);
                return true;
            }
            catch (DataException ex)
            {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在我的Global.asax.cs Application_Start()中我这样做:

if (databaseInitialized == false)
    databaseInitialized = MyContext.InitializeDatabase();
Run Code Online (Sandbox Code Playgroud)

编辑:

我升级到EF 6.1,发现这不再起作用.(/sf/answers/1593936221/)这是我做的修复它:

    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;
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • @Jeff - 我的想法是,我曾经逐字地删除数据库,并使用上述过程(曾经工作)重新创建它.使用您的方法,我必须创建迁移(如您所说),然后运行您描述的代码(确实有效)不同之处在于我不必为EF5中的干净数据库生成迁移.在EF6中,我必须创建迁移,更新我的数据库,然后删除它们.我宁愿只在需要进行生产迁移时创建迁移(而不是在我的每日开发工作流程中) (2认同)

ajd*_*ajd 2

这对我有用(到目前为止......):

var connectionString = "Data Source=localhost;Initial Catalog=Chilli;" + 
    "Integrated Security=True;" + 
    "MultipleActiveResultSets=True;Application Name=ChilliDesktop";

//ooops... you have to create a new, blank database if one does not exist
var bld = new SqlConnectionStringBuilder(connectionString);
var dbName = bld.InitialCatalog; //i.e. Chilli

bld.InitialCatalog = "master";

//a connectionstring pointing at Master
var masterConnectionString = bld.ConnectionString; 

using (var cnn = new SqlConnection(masterConnectionString))
{
  var cmdString = string.Format(
     "if not exists (select * from sys.databases where name='{0}')" + 
     "\r\ncreate database {0}",
     dbName);
   using (var cmd = new System.Data.SqlClient.SqlCommand(cmdString,cnn))
   {
     cmd.Connection.Open();
     cmd.ExecuteNonQuery();
   }                
 }


var connectionInfo = 
    new System.Data.Entity.Infrastructure
        .DbConnectionInfo(connectionString, "System.Data.SqlClient");
//new up your auto-created Migrations Configuration class
var config = new Chilli.Context.Migrations.Configuration();
config.TargetDatabase = connectionInfo;
//new up a Migrator
var migrator = new System.Data.Entity.Migrations
    .DbMigrator(config);
migrator.Update();
//you now have a database

//run your Seed method
using (var dc = new Chilli.Context.Context(connectionString))
{
    Chilli.Context.ChilliContextInitializerHelper.Seed(dc);
}
Run Code Online (Sandbox Code Playgroud)

http://softwaremechanik.wordpress.com/2013/11/04/ef6-if-migrations-are-enabled-cannot-createdatabaseifnotexists/