プロジェクト データ ストレージとして機能するために Entity DbContext を使用しています。そこで、プログラム内から .mdf と .ldf をコピーしたいと思います。(名前を付けて保存コマンド) ファイルをコピーできません。使用中のファイル エラーが発生します。
データベースを切り離し、ファイル (.mdf、.ldf) をコピーし、データベースをファイルに再接続できますか?
プロジェクト データ ストレージとして機能するために Entity DbContext を使用しています。そこで、プログラム内から .mdf と .ldf をコピーしたいと思います。(名前を付けて保存コマンド) ファイルをコピーできません。使用中のファイル エラーが発生します。
データベースを切り離し、ファイル (.mdf、.ldf) をコピーし、データベースをファイルに再接続できますか?
これをつなぎ合わせて見回した後、他の誰かが興味を持っているかもしれません
/// <summary> Detach a database from LocalDB. This MUST be done prior to deleting it. It must also be done after a inadvertent (or ill advised) manual delete.</summary>
/// <param name="dbName">The NAME of the database, not its filename.</param>
/// <param name="directory"></param>
/// <param name="newname"></param>
/// <param name="newdirectory"></param>
/// <remarks></remarks>
public static void CopyDatabase(string dbName, string directory, string newname = null, string newdirectory = null)
{
string dbfilename = null;
// Connect to the MASTER database in order to excute the detach command on it
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder()
{
DataSource = @"(LocalDB)\v11.0",
InitialCatalog = "master",
IntegratedSecurity = true
};
using (SqlConnection connection = new SqlConnection(builder.ToString()))
{
try
{
connection.Open();
DataTable databases = connection.GetSchema("Databases");
foreach (DataRow database in databases.Rows)
{
string databaseName = database.Field<String>("database_name");
short dbID = database.Field<short>("dbid");
DateTime creationDate = database.Field<DateTime>("create_date");
if (databaseName.StartsWith(dbName, true, null) || databaseName.EndsWith(dbName, true, null) || databaseName.EndsWith(dbName + ".mdf", true, null))
{
dbfilename = databaseName;
break;
}
}
if (String.IsNullOrEmpty(dbfilename)) return;
var cmd = connection.CreateCommand();
// Before the database file can be detached from code the workaround below has to be applied.
// http://gunnalag.wordpress.com/2012/02/27/fix-cannot-detach-the-database-dbname-because-it-is-currently-in-use-microsoft-sql-server-error-3703/
//cmd.CommandText = String.Format("SELECT [name] FROM sys.databases d WHERE d.database_id > 4");
cmd.CommandText = String.Format("ALTER DATABASE [{0}] SET OFFLINE WITH ROLLBACK IMMEDIATE", dbfilename);
cmd.ExecuteNonQuery();
try
{
string filename = Path.Combine(directory, dbName + ".mdf");
File.Copy(filename, Path.Combine(newdirectory ?? directory, dbName ?? newname + ".pdk"), true);
filename = Path.Combine(directory, dbName + "_log.ldf");
File.Copy(filename, Path.Combine(newdirectory ?? directory, dbName ?? newname + "_log.lpdf"), true);
}
catch (Exception ex)
{
Helpers.DebugLogger.Caught(ex, "CopyDatabase file copying failed");
}
finally
{
cmd.CommandText = String.Format("ALTER DATABASE [{0}] SET ONLINE", dbfilename);
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
Helpers.DebugLogger.Caught(ex, "CopyDatabase altering database failed");
}
}
}