[英]How to restore a SQL Server backup in .NET Core
我想使用.NET Core还原SQL Server数据库( .bak
)。 这是我在GitHub上的空网站,所以你可以看到当前的配置。
在完整的.NET Framework中恢复数据库非常简单 - 这可以在这里看到。
有没有办法直接从.NET Core中执行此操作,还是需要引用.NET Framework并使用.NET Framework类库?
无论我如何尝试,我都无法让它发挥作用。
编辑
我尝试添加SQLManagementObject,但不能。 我在.NET Core 2.0上。
编辑2
我们的旧项目主要是ADO.NET。 他们(广泛地)使用以下DLL,我无法将其带入我的.NET核心项目:
更新 :使用.Net Core 2.0,您可以使用Microsoft.SqlServer.SqlManagementObjects(140.17265.0)。 SQL Server管理对象(SMO)框架您可以在Windows和Linux下使用SQL SMO。
Microsoft.SqlServer.SqlManagementObjects依赖于System.Data.SqlClient(4.5.0)
简单的SMO备份示例:
ServerConnection serverConnection = new ServerConnection("192.168.1.1", "user", "password");
Server server = new Server(serverConnection);
Database database = server.Databases["AdventureWorks"];
Backup backup = new Backup();
backup.Action = BackupActionType.Database;
backup.BackupSetDescription = "AdventureWorks - full backup";
backup.BackupSetName = "AdventureWorks backup";
backup.Database = "AdventureWorks";
BackupDeviceItem deviceItem = new BackupDeviceItem("AdventureWorks_Full_Backup.bak", DeviceType.File);
backup.Devices.Add(deviceItem);
backup.Incremental = false;
backup.LogTruncation = BackupTruncateLogType.Truncate;
backup.SqlBackup(server);
在.NetCore备份/恢复SQL Server数据库中,您可以使用常见的ADO.NET SqlConnection和SqlCommand对象。 要自定义备份/还原,您需要了解T-SQL BACKUP / RESTORE语句的语法。 请咨询
using System;
using System.Data;
using System.Data.SqlClient;
namespace BackupRestore
{
class Program
{
static void Main(string[] args)
{
BackupDatabase("test", @"C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\test.bak");
RestoreDatabase("test", @"C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\test.bak");
}
private static void RestoreDatabase(string databaseName, string backupPath)
{
string commandText = $@"USE [master];
ALTER DATABASE [{databaseName}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
RESTORE DATABASE [{databaseName}] FROM DISK = N'{backupPath}' WITH FILE = 1, NOUNLOAD, REPLACE, STATS = 5;
ALTER DATABASE [{databaseName}] SET MULTI_USER;";
SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder
{
DataSource = "localhost",
InitialCatalog = "master",
IntegratedSecurity = true
};
using (SqlConnection connection = new SqlConnection(connectionStringBuilder.ConnectionString))
{
connection.Open();
connection.InfoMessage += Connection_InfoMessage;
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = commandText;
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
}
private static void BackupDatabase(string databaseName, string backupPath)
{
string commandText = $@"BACKUP DATABASE [{databaseName}] TO DISK = N'{backupPath}' WITH NOFORMAT, INIT, NAME = N'{databaseName}-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10";
SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder
{
DataSource = "localhost",
InitialCatalog = "master",
IntegratedSecurity = true
};
using (SqlConnection connection = new SqlConnection(connectionStringBuilder.ConnectionString))
{
connection.Open();
connection.InfoMessage += Connection_InfoMessage;
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = commandText;
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
}
private static void Connection_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
Console.WriteLine(e.Message);
}
}
}
要使用新名称(例如newtest)恢复数据库,需要执行next语句
RESTORE DATABASE [newtest]
FROM DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\test.bak' WITH FILE = 1,
MOVE N'test' TO N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\newtest.mdf',
MOVE N'test_log' TO N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\newtest_log.ldf', NOUNLOAD, STATS = 5
您不应该使用SMO,为那些想要在“管理SQL服务器类型应用程序”中管理SQL Server的人创建SMO,您必然会遇到使用简单TSQL命令时不会遇到的版本问题。 TSQL命令在.net Core上运行良好。
我想提到的一件事是你正在打开你的应用程序以获得一些令人不安的权限。
如果您需要恢复数据库,您可能会将其传递给另一个为此设置的任务。 然后你可以用这个“汇集任务”处理这个问题。
假设你接受我上面提到的问题(不是完整列表),你会觉得你想要卸载这个我建议你在SQL服务器中使用一个任务。 您可以安排这些任务运行...第二/分钟/天甚至循环它们。
您可以在任务中执行“N”步骤,1步骤用于“测试还原条件”他执行以下步骤,您可以使用以托管方式执行还原的步骤,当您完成更新日志/发送邮件时等等
使用任务时,您可以使用具有相应权限的用户运行该任务,并且在单用户模式下设置数据库时,您的网站将失去其连接,并将被迫等待还原作业恢复数据库状态。
为了能够使用SQL作业,您需要确保在服务器上激活它。
根据您的任务内容,TSQL语句,如果您希望看起来像这样,请注意您需要验证SQL Server报告的备份文件是否确实存在,这使用了master.sys.xp_cmdshell:
USE Master;
GO
SET NOCOUNT ON
-- 1 - Variable declaration
DECLARE @dbName sysname
DECLARE @backupPath NVARCHAR(500)
DECLARE @cmd NVARCHAR(500)
DECLARE @fileList TABLE (backupFile NVARCHAR(255))
DECLARE @lastFullBackup NVARCHAR(500)
DECLARE @lastDiffBackup NVARCHAR(500)
DECLARE @backupFile NVARCHAR(500)
-- 2 - Initialize variables
SET @dbName = 'Customer'
SET @backupPath = 'D:\SQLBackups\'
-- 3 - get list of files
SET @cmd = 'DIR /b "' + @backupPath + '"'
INSERT INTO @fileList(backupFile)
EXEC master.sys.xp_cmdshell @cmd
-- 4 - Find latest full backup
SELECT @lastFullBackup = MAX(backupFile)
FROM @fileList
WHERE backupFile LIKE '%.BAK'
AND backupFile LIKE @dbName + '%'
SET @cmd = 'RESTORE DATABASE [' + @dbName + '] FROM DISK = '''
+ @backupPath + @lastFullBackup + ''' WITH NORECOVERY, REPLACE'
PRINT @cmd
-- 4 - Find latest diff backup
SELECT @lastDiffBackup = MAX(backupFile)
FROM @fileList
WHERE backupFile LIKE '%.DIF'
AND backupFile LIKE @dbName + '%'
AND backupFile > @lastFullBackup
-- check to make sure there is a diff backup
IF @lastDiffBackup IS NOT NULL
BEGIN
SET @cmd = 'RESTORE DATABASE [' + @dbName + '] FROM DISK = '''
+ @backupPath + @lastDiffBackup + ''' WITH NORECOVERY'
PRINT @cmd
SET @lastFullBackup = @lastDiffBackup
END
-- 5 - check for log backups
DECLARE backupFiles CURSOR FOR
SELECT backupFile
FROM @fileList
WHERE backupFile LIKE '%.TRN'
AND backupFile LIKE @dbName + '%'
AND backupFile > @lastFullBackup
OPEN backupFiles
-- Loop through all the files for the database
FETCH NEXT FROM backupFiles INTO @backupFile
WHILE @@FETCH_STATUS = 0
BEGIN
SET @cmd = 'RESTORE LOG [' + @dbName + '] FROM DISK = '''
+ @backupPath + @backupFile + ''' WITH NORECOVERY'
PRINT @cmd
FETCH NEXT FROM backupFiles INTO @backupFile
END
CLOSE backupFiles
DEALLOCATE backupFiles
-- 6 - put database in a useable state
SET @cmd = 'RESTORE DATABASE [' + @dbName + '] WITH RECOVERY'
PRINT @cmd
更安全的方法是查询服务器并希望该位置有效:
SELECT
bs.database_name,
bs.backup_start_date,
bmf.physical_device_name
FROM
msdb.dbo.backupmediafamily bmf
JOIN
msdb.dbo.backupset bs ON bs.media_set_id = bmf.media_set_id
WHERE
bs.database_name = 'MyDB'
ORDER BY
bmf.media_set_id DESC;
看起来答案在评论中:
“依赖关系”部分中的https://www.nuget.org/packages/Microsoft.SqlServer.SqlManagementObjects列出了“.NETCoreApp 2.0”,这意味着它是一个.NET核心程序集。 因为它取决于https://www.nuget.org/packages/System.Data.SqlClient/ ,这取决于https://www.nuget.org/packages/Microsoft.Win32.Registry/它只能用于Windows,虽然它可以在.NET Core上运行。
或者,使用通过SqlCommand执行的T-SQL语句。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.