C# 分离本地数据库.mdf,复制,附加新文件
我尝试分离本地数据库。mdf将其复制到另一个文件夹中,并在启动时附加新文件,在关闭时复制到旧文件夹 它似乎在启动时起作用,但在关闭表单时出现错误: 进程无法访问文件“C:\ProgramData\MyData\db1.mdf”,因为其他进程正在使用该文件 这是我的密码:C# 分离本地数据库.mdf,复制,附加新文件,c#,sql-server,local,detach,C#,Sql Server,Local,Detach,我尝试分离本地数据库。mdf将其复制到另一个文件夹中,并在启动时附加新文件,在关闭时复制到旧文件夹 它似乎在启动时起作用,但在关闭表单时出现错误: 进程无法访问文件“C:\ProgramData\MyData\db1.mdf”,因为其他进程正在使用该文件 这是我的密码: public Form() { InitializeComponent(); DetachDatabase(); CopyDb(); AttachD
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
并将目标数据库脱机
警告:自担风险使用(例如,您是否可以将与立即回滚一起使用
?)
sp_detach_db
的第二个参数只是避免了统计数据更新(会更快)
现在,您可以安全地将mdf
和ldf
文件从其原始位置移动
假设您的数据库已经脱机,并且您已将db1.mdf
文件移动到D:\which
,我认为您可以做到这一点(我没有测试它,当心)
SQL Server是一个基于服务器的数据库系统-因此最好的方法是不要摆弄
.mdf
文件,只需将数据库留在服务器上,连接到它并使用它来关闭数据库。数据库仍然连接在一起,但我找到了执行此操作的方法var start=new ProcessStartInfo(“sqllocaldb”,“stop MSSQLLocalDB”);start.WindowStyle=ProcessWindowStyle.Hidden;使用(var stop=Process.Start(Start))stop.WaitForExit();start.Arguments=“删除MSSQLLocalDB”;使用(var delete=Process.Start(Start))delete.WaitForExit();我想知道是否没有办法在呼叫返回之前强制DB完全分离(例如,设置单用户模式,重新连接后返回多用户模式)。重新启动流程感觉不是正确的做法,但是,嗯…:另外,如果这是您的主表单,为什么不在表单完全销毁后(以及在构建之前)分离/附加表单,而不是使用事件处理程序?
var commandText = string.Format(@"
USE MASTER;
ALTER DATABASE {0} SET OFFLINE WITH ROLLBACK IMMEDIATE;
EXEC sp_detach_db '{0}', 'true';", "db1");
var commandText = string.Format(@"
USE MASTER;
ALTER DATABASE {0}
MODIFY FILE (
NAME = '{0}',
FILENAME = 'D:\Wherever\{0}.mdf');
ALTER DATABASE {0} SET ONLINE;", "db1");