I try to restore the database like this:
SQL = @\"RESTORE DATABASE MyDataBase TO DISK=\'d:\\MyDATA.BAK\'\";
Cmd = new SqlCommand(SQL, Conn);
I've ended with this solution. Name of my database was Stats This will work without installed MSSQL management studio
public void BackUpDB(string fname)
{
using (SqlConnection cn = new SqlConnection(_cstr))
{
cn.Open();
string cmd = "BACKUP DATABASE [Stats] TO DISK='" + fname + "'";
using (var command = new SqlCommand(cmd, cn))
{
command.ExecuteNonQuery();
}
}
}
public void RestoreDB(string fname)
{
using (SqlConnection cn = new SqlConnection(_cstr))
{
cn.Open();
#region step 1 SET SINGLE_USER WITH ROLLBACK
string sql = "IF DB_ID('Stats') IS NOT NULL ALTER DATABASE [Stats] SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
using (var command = new SqlCommand(sql, cn))
{
command.ExecuteNonQuery();
}
#endregion
#region step 2 InstanceDefaultDataPath
sql = "SELECT ServerProperty(N'InstanceDefaultDataPath') AS default_file";
string default_file = "NONE";
using (var command = new SqlCommand(sql, cn))
{
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
default_file = reader.GetString(reader.GetOrdinal("default_file"));
}
}
}
sql = "SELECT ServerProperty(N'InstanceDefaultLogPath') AS default_log";
string default_log = "NONE";
using (var command = new SqlCommand(sql, cn))
{
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
default_log = reader.GetString(reader.GetOrdinal("default_log"));
}
}
}
#endregion
#region step 3 Restore
sql = "USE MASTER RESTORE DATABASE [Stats] FROM DISK='" + fname + "' WITH FILE = 1, MOVE N'Stats' TO '" + default_file + "Stats.mdf', MOVE N'Stats_Log' TO '"+ default_log+ "Stats_Log.ldf', NOUNLOAD, REPLACE, STATS = 1;";
using (var command = new SqlCommand(sql, cn))
{
command.ExecuteNonQuery();
}
#endregion
#region step 4 SET MULTI_USER
sql = "ALTER DATABASE [Stats] SET MULTI_USER";
using (var command = new SqlCommand(sql, cn))
{
command.ExecuteNonQuery();
}
#endregion
}
}
Your connection string should have a master
database as default catalog to connect to.
public void Restore(string Filepath)
{
try
{
if(con.State == ConnectionState.Closed)
{
con.Open();
}
SqlCommand cmd1 = new SqlCommand("ALTER DATABASE [" + Database + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE ", con);
cmd1.ExecuteNonQuery();
SqlCommand cmd2 = new SqlCommand("USE MASTER RESTORE DATABASE [" + Database + "] FROM DISK='" + Filepath + "' WITH REPLACE", con);
cmd2.ExecuteNonQuery();
SqlCommand cmd3 = new SqlCommand("ALTER DATABASE [" + Database + "] SET MULTI_USER", con);
cmd3.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
con.Close();
}
You must connect to the database server via a different database.
So your connection string should take you to say "Master" or another database on the server, then you can complete the task at hand.
Your DB connection is most likely to the database you're trying to restore. So there is a DB shared lock which prevents the restore of your db
Try this
SQL = @"USE master BACKUP DATABASE MyDataBase TO DISK='d:\MyDATA.BAK'";
Or change the connection details to use master DB
I prefer to use SMO to restore a backup:
Microsoft.SqlServer.Management.Smo.Server smoServer =
new Server(new ServerConnection(server));
Database db = smoServer.Databases['MyDataBase'];
string dbPath = Path.Combine(db.PrimaryFilePath, 'MyDataBase.mdf');
string logPath = Path.Combine(db.PrimaryFilePath, 'MyDataBase_Log.ldf');
Restore restore = new Restore();
BackupDeviceItem deviceItem =
new BackupDeviceItem('d:\MyDATA.BAK', DeviceType.File);
restore.Devices.Add(deviceItem);
restore.Database = backupDatabaseTo;
restore.FileNumber = restoreFileNumber;
restore.Action = RestoreActionType.Database;
restore.ReplaceDatabase = true;
restore.SqlRestore(smoServer);
db = smoServer.Databases['MyDataBase'];
db.SetOnline();
smoServer.Refresh();
db.Refresh();
You'll need references to Microsoft.SqlServer.Smo, Microsoft.SqlServer.SmoExtended, and Microsoft.SqlServer.Management.Sdk.Sfc