分离本地数据库.mdf,复制,附加新文件

Detach local database .mdf, copy, attach the new file

我尝试分离我的本地数据库 .mdf 将其复制到另一个文件夹并在启动时附加新文件并在关闭时复制到旧文件夹。

它似乎在启动时有效,但在关闭表单时出现错误:

The process cannot access the file 'C:\ProgramData\MyData\db1.mdf' because it is being used by another process.

这是我的代码:

    public Form()
    {
        InitializeComponent();
        DetachDatabase();
        CopyDb();
        AttachDatabase();
        AppDomain.CurrentDomain.SetData("DataDirectory", Data.MyNewFolder);    
    }


    public static bool DetachDatabase()
    {
        try
        {

            string connectionString = String.Format(@"Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True");
            using (var cn = new SqlConnection(connectionString))
            {
                cn.Open();
                SqlCommand cmd = cn.CreateCommand();
                cmd.CommandText = String.Format("exec sp_detach_db '{0}'", "db1");
                cmd.ExecuteNonQuery();
                cmd.CommandText = String.Format("exec sp_detach_db '{0}'", "db2");
                cmd.ExecuteNonQuery();
                return true;
            } 
        }
        catch
        {
            return false;
        }
    }

    public static bool AttachDatabase()
    {
        try
        {
            string connectionString = String.Format(@"Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True");
            using (var cn = new SqlConnection(connectionString))
            {
                cn.Open();
                SqlCommand cmd = cn.CreateCommand();
                cmd.CommandText = String.Format("exec sys.sp_attach_db    db1,    'db1.mdf'");
                cmd.CommandText = String.Format("exec sys.sp_attach_db    db2,    'db2.mdf'");
                cmd.ExecuteNonQuery();
                return true;
            }
        }
        catch
        {
            return false;
        }
    }

    private void Frm_FormClosing(object sender, FormClosingEventArgs e)
    {
        LocalDB.DetachDatabase();
        CopyDb();
        LocalDB.AttachDatabase();
    }

这样做的好方法是什么?

谢谢

您需要切换到 master 并将目标数据库置于离线状态

警告:使用风险自负(例如,您可以使用 WITH ROLLBACK IMMEDIATE 吗?)

var commandText = string.Format(@"
    USE MASTER;
    ALTER DATABASE {0} SET OFFLINE WITH ROLLBACK IMMEDIATE;
    EXEC sp_detach_db '{0}', 'true';", "db1");

sp_detach_db 的第二个参数只是避免统计更新(会更快)

您现在可以安全地将 mdfldf 文件从其原始位置移动

假设您的数据库已经脱机并且您已将 db1.mdf 文件移动到 D:\Whatever,我认为您可以这样做(我没有测试它,当心 )

var commandText = string.Format(@"
    USE MASTER;
    ALTER DATABASE {0}
      MODIFY FILE (
        NAME = '{0}',
        FILENAME = 'D:\Wherever\{0}.mdf');
    ALTER DATABASE {0} SET ONLINE;", "db1");