I have an MDF file that I\'m attaching to my local SQL server during testing with MSTEST and I don\'t want to have to go delete those temporary databases by hand after I\'ve
Take a look at the SMO (SQL Server Management Objects) .NET wrappers.
These allow you to manage all aspects of SQL Server from code, including deleting of databases.
The database object has a Drop method.
The code below is to illustrate how you could use the object model, though I have not tested it:
var server = new Server(serverName); // Can use overload that specifies
foreach (Database db in server.Databases)
{
if (db.Name.ToLower().Contains(testDatabaseIdentifier))
{
databasesToDelete.Add(db.Name);
}
}
databasesToDelete.ForEach(x =>
{
Database db = new Database(server, x);
db.Refresh();
db.Drop();
});
Try with this:
sqlCommandText = "DROP DATABASE [NAME]";
sqlCommand = new SqlCommand(sqlCommandText , connection);
sqlCommand.ExecuteNonQuery();
I think this would help.
Instead of using the Database
type to delete a database in TestCleanup, I would recommend to use the Microsoft.SqlServer.Management.Smo.Server.KillDatabase
method. In addition, this will close all existing SQL connections before the database is deleted. Thus your unit tests (or rather integration tests) might leave connections open and this will have no effect on the cleanup method.
var server = new Server(SqlServerName);
server.KillDatabase(DatabaseName);
feO2x's answer works great but he didn't give code. The following works if you have your database connection string in your app.config.
using System.Configuration;
using System.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
public class Foo
{
public static void DropDatabase(string connectionName)
{
using (
var sqlConnection =
new SqlConnection(
ConfigurationManager.ConnectionStrings[connectionName]
.ConnectionString))
{
var serverConnection = new ServerConnection(sqlConnection);
var server = new Microsoft.SqlServer.Management.Smo.Server(
serverConnection);
server.KillDatabase(sqlConnection.Database);
}
}
}
You must reference System.Data, *System.Configuratio*n, Microsoft.SqlServer.ConnectionInfo, Microsoft.SqlServer.Management.Sdk.Sfc, and Microsoft.SqlServer.Management.Smo.
I. Create Resources file (Resources.rsx) and write sql queries:
DECLARE @DatabaseName nvarchar(50)
SET @DatabaseName = N'{0}'
DECLARE @SQL varchar(max)
SELECT @SQL = COALESCE(@SQL,'') + 'Kill ' + Convert(varchar, SPId) + ';'
FROM MASTER..SysProcesses
WHERE DBId = DB_ID(@DatabaseName) AND SPId <> @@SPId
EXEC(@SQL)
IF EXISTS(select * from sys.databases where name='{0}')
DROP DATABASE [{0}]
II. Add MsSqlDatabaseTestsHelper class into the test project
public class MsSqlDatabaseTestsHelper
{
private readonly string _connectionString;
public MsSqlDatabaseTestsHelper(string connectionString)
{
_connectionString = connectionString;
}
private void ExecuteNonQuery(string sql)
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
command.CommandText = sql;
command.ExecuteNonQuery();
}
}
public void CreateDatabase(string databaseName)
{
ExecuteNonQuery("CREATE DATABASE {0}".Set(databaseName));
}
public void DropDatabase(string databaseName)
{
try
{
ExecuteNonQuery(Resources.SQL_KillConnections
.Set(databaseName));
}
catch (Exception)
{
throw new Exception("Can't kill database '{0}' connections"
.Set(databaseName));
}
try
{
ExecuteNonQuery(Resources.SQL_DropDatabaseIfExists
.Set(databaseName));
}
catch (Exception)
{
throw new Exception("Can't drop database '{0}'"
.Set(databaseName));
}
}
}
III. Use database helper in your unit tests
[TestFixture]
public class CmsPageRepositoryTests
{
private readonly MsSqlDatabaseTestsHelper _msSqlDatabaseTestsHelper =
new MsSqlDatabaseTestsHelper(ConnectionStringWithoutDatabase);
private const string ConnectionStringWithoutDatabase =
@"server=.\SqlExpress;uid=sa;pwd=1;";
private const string DatabaseName = "TestPersistence";
[SetUp]
public void SetUp()
{
_msSqlDatabaseTestsHelper.DropDatabase(DatabaseName);
_msSqlDatabaseTestsHelper.CreateDatabase(DatabaseName);
}
[TearDown]
public void TearDown()
{
_msSqlDatabaseTestsHelper.DropDatabase(DatabaseName);
}
[Test]
public void TestSomethingWithDatabaseUsing()
{
}
}
or try this
var sqlCommandText = "DROP DATABASE [dbName]";
var sqlConnection = new SqlConnection(connectionstring);
var sqlCommand = new SqlCommand(sqlCommandText, sqlConnection);
sqlConnection.OpenAsync();
sqlCommand.ExecuteNonQuery();