快速问题是“如何让我的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连接字符串?
答案 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上只有一个数据库,因此很难使用DropCreateDatabaseAlways
或DropCreateDatabaseIfModelChanges
初始值设定项。
我最终编写了最大数据库表的内容脚本,以便以后可以恢复它们。
接下来,我删除了整个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中,在对话框中输入连接字符串用户和密码,然后运行脚本。
只有几张桌子需要更新,而且顺利进行,然后我准备好迎接下一次挑战。