デプロイメントで LocalDB .mdf ファイルを使用する場合、データベース ファイルの移動、削除、またはバックアップが必要になることがよくあります。LocalDB はまだこのファイルの登録を保持しているため、単純に削除するとエラーが発生するため、最初にこのファイルをデタッチすることが最も重要です。
では、LocalDB .mdf ファイルはコードでどのように分離されるのでしょうか?
デプロイメントで LocalDB .mdf ファイルを使用する場合、データベース ファイルの移動、削除、またはバックアップが必要になることがよくあります。LocalDB はまだこのファイルの登録を保持しているため、単純に削除するとエラーが発生するため、最初にこのファイルをデタッチすることが最も重要です。
では、LocalDB .mdf ファイルはコードでどのように分離されるのでしょうか?
私も同じ問題を抱えていて、どう対処するかを考えていました。
3つのアプローチがあります。
データベースの操作の最後 (または操作中) に切り離す
LinqToSQLで接続を閉じる方法が見つかりませんでしたが、実際には必要ありません。次のコードを実行するだけです。
var db = @"c:\blablabla\database1.mdf";
using (var master = new DataContext(@"Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True"))
{
master.ExecuteCommand(@"ALTER DATABASE [{0}] SET OFFLINE WITH ROLLBACK IMMEDIATE", db);
master.ExecuteCommand(@"exec sp_detach_db '{0}'", db);
}
その後、何もクエリを試行しないことを確認してくださいdb
(または、再度添付してください)。
開始時にデタッチ
に接続する前にdb
、デタッチは次のように簡単です。
var db = @"c:\blablabla\database1.mdf";
using (var master = new DataContext(@"Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True"))
master.ExecuteCommand(@"exec sp_detach_db '{0}'", db);
これは私のニーズに非常によく合っています。なぜなら、私はアプリケーションを開始するための遅延を気にしないからです (この場合、db
常にアタッチする必要があるため)。
System.Data.SqlClient.SqlException (0x80131904): データベース 'c:\blablabla\database1.mdf' は既に存在します。別のデータベース名を選択してください。
これは、データベース ファイルが削除されていて、プログラムで作成しようとした場合に発生します
// DataContext
if (!DatabaseExists())
CreateDatabase();
別の方法
sqllocaldb
次のようにコマンド ライン ツールを実行することもできます。
var start = new ProcessStartInfo("sqllocaldb", "stop v11.0");
start.WindowStyle = ProcessWindowStyle.Hidden;
using (var stop = Process.Start(start))
stop.WaitForExit();
start.Arguments = "delete v11.0";
using (var delete = Process.Start(start))
delete.WaitForExit();
サーバーを停止し、すべてのデータベースを切り離します。LocalDBを使用する他のアプリケーションがある場合、次回クエリを実行しようとすると遅延が発生します。
いくつかの場所からの回答をつなぎ合わせる必要があったため、ここに投稿します 。 SQL Server オブジェクト エクスプローラーを使用して、デタッチする前に手動で削除した後、Visual Studio から .mdf ファイルを手動でデタッチできます。
''' <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>
''' <remarks></remarks>
Private Sub DetachDatabase(dbName As String)
Try
'Close the connection to the database.
myViewModel.CloseDatabase()
'Connect to the MASTER database in order to excute the detach command on it.
Dim connectionString = String.Format("Data Source=(LocalDB)\v11.0;Initial Catalog=master;Integrated Security=True")
Using connection As New SqlConnection(connectionString)
connection.Open()
Dim cmd = connection.CreateCommand
'--Before the database file can be detached from code the workaround below has to be applied.
'http://web.archive.org/web/20130429051616/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("ALTER DATABASE [{0}] SET OFFLINE WITH ROLLBACK IMMEDIATE", dbName)
cmd.ExecuteNonQuery()
'--
'--Now detach
cmd.CommandText = String.Format("exec sp_detach_db '{0}'", dbName)
cmd.ExecuteNonQuery()
'--
End Using
Catch ex As Exception
'Do something meaningful here.
End Try
End Sub