2011-03-02 18 views
10

Tengo un archivo MDF que estoy adjuntando a mi servidor SQL local durante la prueba con MSTEST y no quiero tener que ir a borrar esas bases de datos temporales a mano después de ejecutar el conjunto de prueba 50 veces. (Ya lo he hecho y no me gusta>. <) Estoy buscando una manera de eliminar la base de datos del servidor después de que haya terminado con las pruebas, durante mi método TestCleanup. Solo necesito un poco de orientación sobre qué declaraciones SQL usaría para hacer esto.Borrando la base de datos de C#

¿Pensamientos?

¡Thx por adelantado! : D

EDITAR (Por Monkey Software, desde editar rechazado de OP a la respuesta de ODED)

Este es el código que funcionó para mí:

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(); 
}); 
+0

¿Quiere decir eliminar el archivo MDF real? Utilizaría métodos de eliminación de archivos normales del marco para eso. Si quiere decir eliminar las tablas en los MDE, es una serie simple de declaraciones 'DELETE FROM tableName'. –

+0

Estuve investigando algo similar hace un tiempo y terminé usando SQLCE para mis pruebas automáticas. ¿Esta sería una opción para ti también? –

+0

@Robert, perdón por eso debería haber especificado. No es el mdf en sí, sino solo el db que se creó cuando adjunté el mdf – khr055

Respuesta

14

Tome un vistazo a la SMO (SQL Objetos de administración de servidor) .NET wrappers.

Estos le permiten administrar todos los aspectos de SQL Server desde el código, incluida la eliminación de bases de datos.

El objeto de base de datos tiene un método Drop.

El código siguiente es ilustrar cómo se puede utilizar el modelo de objetos, aunque no lo he probado:

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(); 
}); 
+0

Iterating sobre el servidor. Las bases de datos eran la clave para mí. Puedo resolver el resto desde aquí. ¡Gracias! – khr055

+0

@Mike - me alegro de que esto sea de ayuda :) – Oded

+0

Realicé algunos cambios en el código, ya que eliminar el db en el foreach modifica la colección, lo que provoca una excepción. Además, descubrí que simplemente descartando el db sin refrescarlo también causa una excepción. – khr055

8

intento con esto:

sqlCommandText = "DROP DATABASE [NAME]"; 
sqlCommand = new SqlCommand(sqlCommandText , connection); 
sqlCommand.ExecuteNonQuery(); 

Creo que esto ayudaría.

+0

Para el código EntityFramework Primero, puede usar esto: '_db.Database.ExecuteSqlCommand (TransactionalBehavior.DoNotEnsureTransaction," use master; drop database [mydatabase] "'. – deerchao

4

En lugar de utilizar el tipo Database para eliminar una base de datos en TestCleanup, recomendaría utilizar el método Microsoft.SqlServer.Management.Smo.Server.KillDatabase. Además, esto cerrará todas las conexiones SQL existentes antes de que se elimine la base de datos. Por lo tanto, las pruebas unitarias (o más bien las pruebas de integración) pueden dejar conexiones abiertas y esto no tendrá ningún efecto en el método de limpieza.

var server = new Server(SqlServerName); 
server.KillDatabase(DatabaseName); 
4

La respuesta de feO2x funciona muy bien, pero no dio el código. Lo siguiente funciona si tiene su cadena de conexión de base de datos en su 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); 
     } 
    } 
} 

Debe hacer referencia System.Data, System.Configuratio * * n, Microsoft.SqlServer.ConnectionInfo, Microsoft.SqlServer.Management.Sdk.Sfc y Microsoft.SqlServer.Management .Smo.

5

Aquí es cómo lo hace utilizando la versión de Entity Framework 6

System.Data.Entity.Database.Delete(connectionString); 
+0

Gracias por compartir. ¡Eso es lo que quiero! – Rapunzo

2

I. Crear archivo de recursos (Recursos.RSX) y escribir consultas SQL:

  • SQL_KillConnections

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) 
  • SQL_DropDatabaseIfExists

IF EXISTS(select * from sys.databases where name='{0}') 
DROP DATABASE [{0}] 

II. Añadir MsSqlDatabaseTestsHelper clase en el proyecto de prueba

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 el ayudante de base de datos en las pruebas de su unidad

[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() 
    { 
    } 
} 
Cuestiones relacionadas