EFCore を LocalDB (SQL Server Express) で動かした際、DB ファイルを消したいのにプロセスにロックされている場合
2 min readFeb 1, 2019
--
原因は、LocalDB のプロセスがファイルをアタッチしたままだから。これは、コード側で Dispose() しても GC してもダメ。呼び出し元のプロセスが落ちるまでは mdf ファイルは握られている。
単体テストを並列で走らせたりした際に困ることになる。
で、この問題は、利用し終わった際に、自分で自分をデタッチしてあげることで解決する。
例えば、単体テスト用のラッパー DbContext で、以下のように、生コンテキストを使って、自分をデタッチしてあげるだけ。
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
var sql =
"declare @dbname varchar(max);"
+ "set @dbname = quotename(db_name());"
+ "exec('ALTER DATABASE ' + @dbname + ' SET OFFLINE WITH ROLLBACK IMMEDIATE;'); "
+ "exec('sp_detach_db ' + @dbname + ';'); "; Context.Database.ExecuteSqlCommand(sql);
Context.Dispose();
}
disposedValue = true;
}
}
これで mdf ファイルはデタッチされ解放される。あとは、コードのなかで File.Delete()
してもよし、ディレクトリ毎消してもよし。