Saltar al contenido

“No se puede eliminar la base de datos porque actualmente está en uso”. ¿Como arreglar?

Este grupo de especialistas luego de ciertos días de investigación y de juntar de datos, hemos dado con los datos necesarios, queremos que te resulte útil para tu plan.

Solución:

El problema es que su aplicación probablemente aún tenga alguna conexión con la base de datos (u otra aplicación también tenga conexión). La base de datos no se puede eliminar donde hay otra conexión abierta. El primer problema probablemente se puede resolver desactivando la agrupación de conexiones (agregar Pooling=false a tu conexión string) o borre el grupo antes de eliminar la base de datos (llamando SqlConnection.ClearAllPools()).

Ambos problemas se pueden resolver forzando la eliminación de la base de datos, pero para eso necesita un inicializador de base de datos personalizado donde cambia la base de datos al modo de usuario único y luego la elimina. Aquí hay un ejemplo de cómo lograrlo.

¡Me estaba volviendo loco con esto! Tengo una conexión de base de datos abierta dentro SQL Server Management Studio (SSMS) y una consulta de tabla abierta para ver el resultado de algunas pruebas unitarias. Cuando vuelva a ejecutar las pruebas dentro de Visual Studio, quiero que drop la base de datos siempre INCLUSO SI la conexión está abierta en SSMS.

Esta es la forma definitiva de deshacerse de Cannot drop database because it is currently in use:

Inicialización de la base de datos de Entity Framework

El truco es anular InitializeDatabase método dentro de la costumbre Initializer.

Copio la parte relevante aquí por el bien de goodDUPLICACIÓN… 🙂

Si la base de datos ya existe, puede tropezar con el caso de tener un error. Puede surgir la excepción “No se puede descartar la base de datos porque actualmente está en uso”. Este problema ocurre cuando una conexión activa permanece conectada a la base de datos que está en proceso de eliminación. Un truco es anular el método InitializeDatabase y modificar la base de datos. Esto le dice a la base de datos que cierre todas las conexiones y si una transacción está abierta para revertirla.

public class CustomInitializer : DropCreateDatabaseAlways

    public override void InitializeDatabase(YourContext context)
    
        context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction
            , string.Format("ALTER DATABASE [0] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", context.Database.Connection.Database));

        base.InitializeDatabase(context);
    

    protected override void Seed(YourContext context)
    
        // Seed code goes here...

        base.Seed(context);
    

Este es un (re) inicializador de base de datos realmente agresivo para el código EF primero con migraciones; úsalo bajo tu responsabilidad, pero parece funcionar bastante repetitivamente para mí. Va a;

  1. Desconecte a la fuerza cualquier otro cliente de la base de datos
  2. Eliminar la base de datos.
  3. Reconstruya la base de datos con migraciones y ejecute el método Seed
  4. ¡Tomar las edades! (observe el límite de tiempo de espera para su marco de prueba; un tiempo de espera predeterminado de 60 segundos podría no ser suficiente)

Aquí está la clase;

public class DropCreateAndMigrateDatabaseInitializer: IDatabaseInitializer 
    where TContext: DbContext
    where TMigrationsConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration, new()

    public void InitializeDatabase(TContext context)
    
        if (context.Database.Exists())
        
            // set the database to SINGLE_USER so it can be dropped
            context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, "ALTER DATABASE [" + context.Database.Connection.Database + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE");

            // drop the database
            context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, "USE master DROP DATABASE [" + context.Database.Connection.Database + "]");
        

        var migrator = new MigrateDatabaseToLatestVersion();
        migrator.InitializeDatabase(context);

    

Úselo así;

public static void ResetDb()

    // rebuild the database
    Console.WriteLine("Rebuilding the test database");
    var initializer = new DropCreateAndMigrateDatabaseInitializer();
    Database.SetInitializerinitializer);

    using (var ctx = new MyContext())
    
        ctx.Database.Initialize(force: true);
    

También uso ‘Pooling= de Ladislav Mrnkafalse’ truco, pero no estoy seguro de si es necesario o solo una medida de cinturón y tirantes. Sin duda contribuirá a ralentizar más la prueba.

Te mostramos las reseñas y valoraciones de los lectores

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *