program story

"현재 사용 중이므로 데이터베이스를 삭제할 수 없습니다."

inputbox 2020. 12. 11. 08:08
반응형

"현재 사용 중이므로 데이터베이스를 삭제할 수 없습니다." 어떻게 고치는 지?


이 간단한 코드를 사용하면 "현재 사용 중이기 때문에"test_db "데이터베이스를 삭제할 수 없습니다"(CleanUp 메서드)가 실행됩니다.

[TestFixture]
public class ClientRepositoryTest
{
    private const string CONNECTION_STRING = "Data Source=.;Initial Catalog=test_db;Trusted_Connection=True";
    private DataContext _dataCntx;

    [SetUp]
    public void Init()
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<DataContext>());
        _dataCntx = new DataContext(CONNECTION_STRING);
        _dataCntx.Database.Initialize(true);
    }

    [TearDown]
    public void CleanUp()
    {
        _dataCntx.Dispose();
        Database.Delete(CONNECTION_STRING);
    }
}

DataContext에는 이와 같은 속성이 하나 있습니다.

 public DbSet<Client> Clients { get; set; }

내 코드에서 데이터베이스를 제거하려면 어떻게해야합니까? 감사


문제는 응용 프로그램이 여전히 데이터베이스에 대한 일부 연결을 보유하고 있거나 다른 응용 프로그램도 연결을 보유한다는 것입니다. 열려있는 다른 연결이있는 데이터베이스는 삭제할 수 없습니다. 첫 번째 문제는 연결 풀링을 끄 Pooling=false거나 (연결 문자열에 추가 ) 데이터베이스를 삭제하기 전에 풀을 지우면 (을 호출하여 SqlConnection.ClearAllPools()) 해결할 수 있습니다 .

두 가지 문제는 데이터베이스를 강제로 삭제하여 해결할 수 있지만이를 위해서는 데이터베이스를 단일 사용자 모드로 전환 한 후 삭제하는 사용자 지정 데이터베이스 이니셜 라이저가 필요합니다. 여기에 그것을 달성하는 방법을 몇 가지 예입니다.


나는 이것에 미쳐 가고 있었다! 내부에 열린 데이터베이스 연결이 SQL Server Management Studio (SSMS)있고 일부 단위 테스트의 결과를보기 위해 테이블 ​​쿼리가 열려 있습니다. 다시 실행 비주얼 스튜디오 I 내부 테스트가 원하는 경우 drop데이터베이스 항상 경우에도 연결이 SSMS에 열려 있습니다.

제거하는 확실한 방법은 다음과 같습니다 Cannot drop database because it is currently in use.

Entity Framework 데이터베이스 초기화

트릭은 InitializeDatabasecustom 내부의 메서드 를 재정의 하는 것 Initializer입니다.

good 복제를 위해 여기에 관련 부분을 복사했습니다 ... :)

데이터베이스가 이미 존재하는 경우 오류가 발생할 수 있습니다. "현재 사용 중이므로 데이터베이스를 삭제할 수 없습니다"예외가 발생할 수 있습니다. 이 문제는 활성 연결이 삭제중인 데이터베이스에 계속 연결되어있을 때 발생합니다. 트릭은 InitializeDatabase 메서드를 재정의하고 데이터베이스를 변경하는 것입니다. 이것은 데이터베이스에 모든 연결을 닫고 트랜잭션이이 연결을 롤백하기 위해 열려 있는지 알려줍니다.

public class CustomInitializer<T> : DropCreateDatabaseAlways<YourContext>
{
    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);
    }
}

이것은 마이그레이션이있는 EF 코드 우선을위한 매우 공격적인 데이터베이스 (재) 이니셜 라이저입니다. 당신의 위험에 그것을 사용하지만 그것은 나를 위해 꽤 반복적으로 실행되는 것 같습니다. 그것은 것입니다;

  1. DB에서 다른 클라이언트를 강제로 분리
  2. DB를 삭제합니다.
  3. 마이그레이션을 통해 DB를 재 구축하고 Seed 메서드를 실행합니다.
  4. 나이를 먹다! (테스트 프레임 워크의 제한 시간을 확인하십시오. 기본 60 초 제한 시간은 충분하지 않을 수 있습니다.)

여기에 수업이 있습니다.

public class DropCreateAndMigrateDatabaseInitializer<TContext, TMigrationsConfiguration>: IDatabaseInitializer<TContext> 
    where TContext: DbContext
    where TMigrationsConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<TContext>, 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<TContext, TMigrationsConfiguration>();
        migrator.InitializeDatabase(context);

    }
}

다음과 같이 사용하십시오.

public static void ResetDb()
{
    // rebuild the database
    Console.WriteLine("Rebuilding the test database");
    var initializer = new DropCreateAndMigrateDatabaseInitializer<MyContext, MyEfProject.Migrations.Configuration>();
    Database.SetInitializer<MyContext>initializer);

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

나는 또한 Ladislav Mrnka의 'Pooling = false'트릭을 사용하지만 이것이 필요한지 아니면 그냥 벨트와 브레이스 측정인지 확실하지 않습니다. 그것은 확실히 테스트 속도를 더 늦추는 데 기여할 것입니다.


이러한 솔루션 중 어느 것도 나를 위해 일하지 않았습니다. 결국 작동하는 확장 메서드를 작성했습니다.

private static void KillConnectionsToTheDatabase(this Database database)
{
    var databaseName = database.Connection.Database;
    const string sqlFormat = @"
             USE master; 

             DECLARE @databaseName VARCHAR(50);
             SET @databaseName = '{0}';

             declare @kill varchar(8000) = '';
             select @kill=@kill+'kill '+convert(varchar(5),spid)+';'
             from master..sysprocesses 
             where dbid=db_id(@databaseName);

             exec (@kill);";

    var sql = string.Format(sqlFormat, databaseName);
    using (var command = database.Connection.CreateCommand())
    {
        command.CommandText = sql;
        command.CommandType = CommandType.Text;

        command.Connection.Open();

        command.ExecuteNonQuery();

        command.Connection.Close();
    }
}

Pooling=falseLadislav Mrnka가 말한 것처럼 추가하려고 시도 했지만 항상 오류가 발생했습니다.
내가 사용하고 SQL Server Management Studio를 하고 심지어 내가 가까이 모든 연결하면, 나는 오류가 발생합니다.

Sql Server Management Studio닫으면 데이터베이스가 삭제됩니다. :)
도움이되기를 바랍니다.


I got the same error. In my case, I just closed the connection to the database and then re-connected once the in my case the new model was added and a new controller was scaffolded. That is however a very simple solution and not recommended for all scenarios if you want to keep your data.


I got the same problem back then. Turns out the solution is to close the connection in Server Explorer tab in Visual Studio. So maybe you could check whether the connection is still open in the Server Explorer.


Its simple because u're still using the same db somewhere, or a connection is still open. So just execute "USE master" first (if exist, but usually is) and then drop the other db. This always should work!

Grz John

참고URL : https://stackoverflow.com/questions/7004701/cannot-drop-database-because-it-is-currently-in-use-how-to-fix

반응형