10

デプロイメントで LocalDB .mdf ファイルを使用する場合、データベース ファイルの移動、削除、またはバックアップが必要になることがよくあります。LocalDB はまだこのファイルの登録を保持しているため、単純に削除するとエラーが発生するため、最初にこのファイルをデタッチすることが最も重要です。

では、LocalDB .mdf ファイルはコードでどのように分離されるのでしょうか?

4

3 に答える 3

12

私も同じ問題を抱えていて、どう対処するかを考えていました。

3つのアプローチがあります。

  1. データベースの操作の最後 (または操作中) に切り離す

    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(または、再度添付してください)。

  2. 開始時にデタッチ

    に接続する前に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();
    
  3. 別の方法

    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を使用する他のアプリケーションがある場合、次回クエリを実行しようとすると遅延が発生します。

于 2014-04-01T16:23:13.417 に答える
11

いくつかの場所からの回答をつなぎ合わせる必要があったため、ここに投稿します 。 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
于 2013-04-26T19:31:45.070 に答える