EFCore を LocalDB (SQL Server Express) で動かした際、DB ファイルを消したいのにプロセスにロックされている場合

arichika.taniguchi
Feb 1, 2019 · 2 min read

原因は、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() してもよし、ディレクトリ毎消してもよし。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store