丢失的迁移和Azure数据库现在不同步

时间:2015-01-09 03:49:58

标签: asp.net-mvc azure ef-code-first entity-framework-6

快速问题是“如何让我的Azure数据库与我的本地数据库同步恢复?”

详细说明: 我一直在我的项目中使用实体框架,它与内置了Identity 2的ASP.NET MVC 5示例项目没有什么不同。

有两个数据库上下文,一个来自Identity,名为ApplicationDbContext(aspnet_somethingUserDB),另一个名为StoreInitialTestContext(store_db),来自我的更改。

有趣的是,我将这些上下文中的每一个都放在一个单独的SQL数据库本地,它们只在一个数据库中,在Azure服务上称为store_db。

事情正在顺利进行,两个本地数据库同步,这些数据库与Azure上的单个数据库相同。该网站在本地运行良好,可用于调试和Azure。

通过添加模型对模式进行最后一次更改后,我执行了update-database命令并更新了本地数据库。不幸的是,当我将网站发布到Azure时,在通过“运行代码优先迁移...”选择上下文和复选标记后,Azure数据库没有更新。

查看我的代码,我没有看到任何待处理的迁移,所以我不确定如何让Azure数据库重新同步。

作为最后的努力,我将Azure数据库从Basic设置为Standard,并在本地store_db和Azure store_db之间使用compare schema命令。我确保通过取消选中与aspnet_UsersomethingDb有关的表来仅更新本地store_db中的表。

该操作未成功,因此我尝试撤消对本地更改的问题,并且未在Azure上应用。

这也没有成功,所以我调整了我的网站以避免EntityFramework“模型与数据库差异”崩溃,这样它至少会跛行。

此时,我的本地数据库很好,但是关闭“代码优先迁移”复选框,Azure数据库正在报告:

  

EntityFramework.dll中出现'System.InvalidOperationException'类型的异常,但是   未在用户代码中处理

     

附加信息:支持'StoreInitialTestContext'上下文的模型自此以后发生了变化   数据库已创建。考虑使用Code First Migrations来更新数据库   (http://go.microsoft.com/fwlink/?LinkId=238269)。

打开复选框,报告为:

  

EntityFramework.dll中出现'System.Data.SqlClient.SqlException'类型的异常,但是   未在用户代码中处理

     

附加信息:已经有一个名为'ExtendedUserInformations'的对象   数据库中。

这似乎表明代码优先迁移想要添加对象以使事物同步,但该对象已经存在。

是否有一种快速方法可以使这些数据库同步? Azure中没有那么多数据,所以如果必须,我可以导出一些记录并在重新创建数据库后重新加载它们。

您是否建议使用update-database并指定Azure连接字符串?

1 个答案:

答案 0 :(得分:2)

我最终在这里做的可能不是最简单的方法,但它可能对某人有帮助。


首先,虽然他提出的建议很有意思,但在我的案例中并没有起作用,所以对http://robertgreiner.com/2012/05/using-entity-framework-database-migrations-to-update-a-remote-database/大肆宣传。我应该意识到这一点,但是update-database命令也可以通过使用Azure连接字符串在Azure数据库上运行。

确保将您的数据库缩放到"标准'等级或以上,以避免命令超时和不稳定的操作。 '基本'和'网络'不适合任何事情"有用"。请注意,您可以在" Scaling"下更改层级。数据库的Azure设置可以根据需要随时使用

可以通过从发布设置进行复制和粘贴来获取Azure连接字符串(右键单击您的项目,选择"发布"然后选择"设置")和-ConnectionProviderName需要的是System.Data.Sqlclient,所以命令如下所示:

  

update-database -ConnectionString   "数据源= tcp:' your-sql-server' .database.windows.net,1433;初始目录=' your-db-name&#39 ;;   用户ID = user @' your-sql-server&#39 ;;密码=' sql-server-pwd'


具有两个数据库上下文的示例项目(ApplicationDbContext和我的StoreInitialTestContext)大大增加了复杂性。事实上,每个上下文在本地端都有一个数据库,但Azure上只有一个数据库,因此很难使用DropCreateDatabaseAlwaysDropCreateDatabaseIfModelChanges初始值设定项。

我最终编写了最大数据库表的内容脚本,以便以后可以恢复它们。

接下来,我删除了整个Migrations目录,这有效地禁用了迁移(正如在此处所指出的,没有disable-migrations程序包管理器命令。)

接下来,我为StoreInitialTestContext设置了一个数据库初始化程序,如下所示:

public class StoreInitialTestContextInitializerCreate: DropCreateDatabaseAlways < StoreInitialTestContext > 
{
      protected override void Seed(StoreInitialTestContext context)
      {
        // nothing for now
      }
}

此外,将其注册为适当上下文的数据库初始化程序:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {

        // Drop the StoreInitialContext database and recreate if the model changes
        Database.SetInitializer<StoreInitialTestContext>( new StoreInitialTestContextInitializerCreate());

我曾经在下次网站运行时重新创建包含StoreInitialTestContext的数据库。

完全清理本地数据库后,我转移到Azure。

我去了门户网站并删除了数据库,以便下次我的网站在Azure上运行时可以重新创建它。

我确保将“发布”配置文件中的设置设置为更新数据库,但请注意,“代码优先迁移”选项不可用。

下次在Azure上运行网站时,实体框架没有看到任何数据库,因此它是创建的。

我确保通过列出项目来执行我自己的上下文,并通过注册为用户来执行aspnet Identity部分。在Visual Studio中检查SQL Server对象资源管理器确认已创建所有表。

接下来,是时候从表中恢复数据了,但首先为了避免Azure错误,我设置了我新创建的数据库,该数据库已被创建为&#34; defunct&#34; &#34;网页和#34;数据库层,到标准&#34;层。

然后我将脚本逐个加载到Visual Studio中,在对话框中输入连接字符串用户和密码,然后运行脚本。

只有几张桌子需要更新,而且顺利进行,然后我准备好迎接下一次挑战。