Вот полная программа, которая создает базу данных SQL Server Express и удаляет ее из локального экземпляра, оставляя базу данных только для файлов для воспроизведения.После игры с ним я хочу удалить его.
При запуске метода Main
я могу успешно удалить файлы db из предыдущих запусков.
Однако, если я пытаюсь удалить их в конце метода Main
, операция завершается неудачно с
Процесс не может получить доступ к файлу 'c: \ temp.mdf'потому что он используется другим процессом.
Согласно http://blogs.msdn.com/b/sqlexpress/archive/2008/02/22/sql-express-behaviors-idle-time-resources-usage-auto-close-and-user-instances.aspx, с AUTO_CLOSE, как по умолчанию для SQL Server Express, после 300 мс бездействия SQL Server Express должен освободить доступ кфайл, но, похоже, этого не происходит.
Кто-нибудь знает, как я могу заставить это работать, чтобы я мог убирать за собой?
TIA
using System;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace ConsoleApplication3 {
class Program {
private const string ConnectionStringToFile = @"Data Source=.\SqlExpress;Integrated Security=True;AttachDbFileName={0};User Instance=True";
private const string ConnectionStringToTempDb = @"Data Source=.\SqlExpress;Initial Catalog=TempDb;Integrated Security=True;User Instance=True;";
private const string CreateDbSql = "CREATE DATABASE {0} ON PRIMARY (NAME='{0}', FILENAME='{1}');";
private const string DetachDbSql = "EXEC sp_detach_db '{0}', 'true';";
private static SqlConnection GetConnection(string connectionString) {
var conn = new SqlConnection(connectionString);
Debug.WriteLine("Created", "Connection");
Debug.Indent();
conn.StateChange += ConnectionStateChange;
conn.InfoMessage += ConnectionInfoMessage;
conn.Disposed += ConnectionDisposed;
return conn;
}
private static void ConnectionDisposed(object sender, EventArgs e) {
SqlConnection conn = (SqlConnection)sender;
conn.StateChange -= ConnectionStateChange;
conn.InfoMessage += ConnectionInfoMessage;
conn.Disposed += ConnectionDisposed;
Debug.Unindent();
Debug.WriteLine("Disposed", "Connection");
}
private static void ConnectionInfoMessage(object sender, SqlInfoMessageEventArgs e) {
Debug.WriteLine("InfoMessage: " + e.Message, "Connection");
}
private static void ConnectionStateChange(object sender, System.Data.StateChangeEventArgs e) {
Debug.WriteLine("StateChange: from " + e.OriginalState + " to " + e.CurrentState, "Connection");
}
static void Main() {
const string DbName = "temp";
const string DbPath = "c:\\temp.mdf";
const string DbLogFile = "c:\\temp_log.ldf";
if (File.Exists(DbPath)) File.Delete(DbPath);
if (File.Exists(DbLogFile)) File.Delete(DbLogFile);
using (var conn = GetConnection(ConnectionStringToTempDb)) {
conn.Open();
using (var command = conn.CreateCommand()) {
command.CommandText = string.Format(CreateDbSql, DbName, DbPath);
command.ExecuteNonQuery();
command.CommandText = string.Format(DetachDbSql, DbName);
Debug.WriteLine("Detach result: " + command.ExecuteScalar(), "Database");
}
}
using (var conn = GetConnection(string.Format(ConnectionStringToFile, DbPath))) {
conn.Open();
using (var command = conn.CreateCommand()) {
command.CommandText = "PRINT 'Successfully connected to database.'";
command.ExecuteNonQuery();
command.CommandText = "CREATE TABLE temp (temp int)";
command.ExecuteNonQuery();
command.CommandText = "INSERT temp VALUES (1);";
command.ExecuteNonQuery();
}
}
// takes 300ms apparently: http://blogs.msdn.com/b/sqlexpress/archive/2008/02/22/sql-express-behaviors-idle-time-resources-usage-auto-close-and-user-instances.aspx
Thread.Sleep(1000);
if (File.Exists(DbPath)) File.Delete(DbPath);
if (File.Exists(DbLogFile)) File.Delete(DbLogFile);
}
}
}