Iva*_*van 49 c# asp.net azure visual-studio azure-sql-database
我有一个本地工作的ASP.NET MVC 5项目,每当我需要吹掉数据库时,我只需打开一个新的查询,将可用的数据库下拉列表更改为master,然后关闭我本地数据库上的连接并运行查询"drop database [name]".然后我构建项目,进入包管理器控制台并运行"Update-Database".这似乎重建了一个新的本地数据库,并在我的configuration.cs文件中运行种子方法.
问题是,当我需要在实时环境中测试内容以便我可以更好地测试API时,我将部署到Azure网站和随附的Azure数据库,这很容易做到.我在发布向导中检查了"执行代码首次迁移",大部分时间它都可以运行,我可以运行和调试我的实时版本.有时我需要吹掉那个数据库,然后再从头开始,但我真正找到的唯一方法是进入Azure门户,删除数据库,然后使用相同的名称重新创建它.这需要一些时间来处理Azure,因此这是一个缓慢的测试周期.
有没有一种快速的方法可以将Azure SQL数据库删除/重置为新的,空的,处女状态,然后使用"执行代码优先迁移"重新发布,以使其重新创建表并重新播种数据?
在创建数据库之后,我已经看到了一些关于创建初始迁移的讨论,然后尝试使用Powershell进行某种回滚到初始状态,但是我没有运气让它工作,并且我想同时删除所有数据.也许我刚刚得到了错误的语法或者没有找到足够好的教程.虽然我可以在Azure数据库上运行查询以"删除数据库[x]",但它实际上会按照您的预期杀死SQL Azure数据库实例,您需要返回到门户网站来重新创建它.有时初始状态并不好,因为模型已经更新,所以这可能无用.
我觉得应该有一些更简单快捷的方法来测试实时环境中的变化,因为MS提供了所有这些优秀的工具和快捷方式,但是他们只是为了这个开发阶段而放弃了这个球,还是我错过了什么?
Tom*_*mmy 62
由于我没有使用API方法来执行此操作,因此我们使用此脚本来利用T-SQL查询来清除数据库.
删除每个表(如果需要,还可以维护EF迁移历史记录)
while(exists(select 1 from INFORMATION_SCHEMA.TABLES
where TABLE_NAME != '__MigrationHistory'
AND TABLE_TYPE = 'BASE TABLE'))
begin
declare @sql nvarchar(2000)
SELECT TOP 1 @sql=('DROP TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME
+ ']')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_TYPE = 'BASE TABLE'
exec (@sql)
/* you dont need this line, it just shows what was executed */
PRINT @sql
end
Run Code Online (Sandbox Code Playgroud)
如果需要,首先删除外键
while(exists(select 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE='FOREIGN KEY'))
begin
declare @sql nvarchar(2000)
SELECT TOP 1 @sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME
+ '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
FROM information_schema.table_constraints
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
exec (@sql)
PRINT @sql
end
Run Code Online (Sandbox Code Playgroud)
在我的测试中,这没有问题(除了我在查询中没有DROP TABLE中的where子句,因为我不使用Code First或EF迁移).
Giz*_*399 50
只是为了添加答案,因为接受的答案在Azure上对我不起作用.使用以下脚本删除所有表,并基本上重置azure数据库.它首先删除所有约束,然后删除所有表.
正如@SkorunkaFrantišek所评论的那样,此脚本假定您使用默认的[dbo]模式.虽然您可以用自己的架构名称替换它.
/* Azure friendly */
/* Drop all Foreign Key constraints */
DECLARE @name VARCHAR(128)
DECLARE @constraint VARCHAR(254)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' ORDER BY TABLE_NAME)
WHILE @name is not null
BEGIN
SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
WHILE @constraint IS NOT NULL
BEGIN
SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT [' + RTRIM(@constraint) +']'
EXEC (@SQL)
PRINT 'Dropped FK Constraint: ' + @constraint + ' on ' + @name
SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
END
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' ORDER BY TABLE_NAME)
END
GO
/* Drop all Primary Key constraints */
DECLARE @name VARCHAR(128)
DECLARE @constraint VARCHAR(254)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME)
WHILE @name IS NOT NULL
BEGIN
SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
WHILE @constraint is not null
BEGIN
SELECT @SQL = 'ALTER TABLE [dbo].[' + RTRIM(@name) +'] DROP CONSTRAINT [' + RTRIM(@constraint)+']'
EXEC (@SQL)
PRINT 'Dropped PK Constraint: ' + @constraint + ' on ' + @name
SELECT @constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND CONSTRAINT_NAME <> @constraint AND TABLE_NAME = @name ORDER BY CONSTRAINT_NAME)
END
SELECT @name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME)
END
GO
/* Drop all tables */
DECLARE @name VARCHAR(128)
DECLARE @SQL VARCHAR(254)
SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 ORDER BY [name])
WHILE @name IS NOT NULL
BEGIN
SELECT @SQL = 'DROP TABLE [dbo].[' + RTRIM(@name) +']'
EXEC (@SQL)
PRINT 'Dropped Table: ' + @name
SELECT @name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > @name ORDER BY [name])
END
GO
Run Code Online (Sandbox Code Playgroud)
可悲的是,我无法找到此代码的源代码,因为我已将其保存在我的某个存储库中.我希望它对某人有帮助.
我通常
yourserver.database.windows.net选择了用于SQL Server身份验证选项的用户名和密码)(还记得您需要在Azure门户中添加防火墙例外,以便以这种方式从PC连接到数据库)就如此容易.
然后,由于您提到您具有代码优先迁移方法,因此只需在Azure SQL Server中再次运行迁移(例如,在发布时确保检查为给定sql server连接字符串应用迁移的选项)
我通常删除远程数据库,然后使用命令重新部署应用程序以重新运行迁移.这将使用新表再次创建数据库.种子数据库的代码在我的启动代码中,因此如果数据库中没有值,则在应用程序初始化时随时播种.
这也适用于AspNet Core Mvc(MVC6)
只是为了将我的变体添加到混合中...这一个还考虑了“视图”和“外部表”。它不会在必须与DROP EXTERNAL TABLE一起删除的外部表上使用。这导致原始版本永远旋转。
while(exists(select 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE='FOREIGN KEY'))
begin
declare @sql nvarchar(2000)
SELECT TOP 1 @sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME
+ '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
FROM information_schema.table_constraints
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
exec (@sql)
PRINT @sql
end
while(exists(select 1 from INFORMATION_SCHEMA.TABLES
where TABLE_NAME != 'database_firewall_rules'
AND TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME NOT IN (select name from sys.external_tables)))
begin
declare @sql1 nvarchar(2000)
SELECT TOP 1 @sql1=('DROP TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME != 'database_firewall_rules'
AND TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME NOT IN (select name from sys.external_tables)
exec (@sql1)
PRINT @sql1
end
Run Code Online (Sandbox Code Playgroud)