2015-04-06 3 views
4

J'essaie de restaurer une base de données à partir d'un fichier .BAK en utilisant C# et SMO. C'est mon code.Comment tuer toutes les connexions à une base de données SQL Server en utilisant C# et SMO?

public static void RestoreDatabase() 
{ 
    string dbConnString = Configuration.DatabaseConnectionString; 
    ServerConnection connection = new ServerConnection(@"dbserver\sqlexpress", "user", "password"); 
    Server smoServer = new Server(connection); 

    Restore rstDatabase = new Restore(); 
    rstDatabase.Action = RestoreActionType.Database; 
    rstDatabase.Database = "AppDb"; 

    BackupDeviceItem bkpDevice = new BackupDeviceItem(@"TestData\db-backup.bak", DeviceType.File); 
    rstDatabase.Devices.Add(bkpDevice); 
    rstDatabase.ReplaceDatabase = true; 

    // Kill all processes 
    smoServer.KillAllProcesses(rstDatabase.Database); 

    // Set single-user mode 
    Database db = smoServer.Databases[rstDatabase.Database]; 
    db.DatabaseOptions.UserAccess = DatabaseUserAccess.Single; 
    db.Alter(TerminationClause.RollbackTransactionsImmediately); 

    rstDatabase.SqlRestore(smoServer); 
} 

Cependant, lorsque je tente d'exécuter cette méthode que je reçois le texte suivant (erreur) un message quand il tente de tuer tous les processus:

Ne peut pas utiliser KILL pour tuer votre propre processus.

Je serais très reconnaissant si quelqu'un pouvait aider à résoudre ce problème.

+0

C'est parce qu'il va tuer votre propre processus aussi. Comme votre application est également connectée à SQL Server –

+0

Existe-t-il une solution/solution de contournement pour cela? J'ai essayé de simplement définir la base de données à un seul utilisateur, mais cela n'a pas fonctionné. C'est après cela que j'ai inclus la ligne pour tuer tous les processus. –

+1

Quelle base de données utilisez-vous lors de la connexion? Je pense que c'est AppDB. Changez votre chaîne de connexion pour vous connecter à 'master' à la place. –

Répondre

2

Il m'arrive tout le temps quand j'essaye de reconstituer une base de données et il y a une connexion active quelque part et la base de données ne restaurez pas jusqu'à ce qu'il n'y ait plus de connexions actives à la base de données.

Habituellement, ce que je fais est, j'exécute le jeu de commandes suivant pour déconnecter tout le monde, puis restaurer la base de données.

ALTER DATABASE [DatabaseName] 
SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 
GO 

-- at this point all the users will be disconnected and the database is in 
-- single-user mode 

Use [DatabaseName] --<-- Grab that single connection 
GO 

Use [master]  --<-- Disconnect from database and connect to Master DB for restore 
GO 

RESTORE DATABASE [DatabaseName] --<-- Finally restore database tara 
FROM DISK ......... 
GO 
+0

Donc, je suppose que SMO n'est pas la voie à suivre alors? –

+0

Peut-être qu'il y a une façon plus élégante de le faire avec SMO, je viens de partager mon expérience avec vous. L'expérience la plus douloureuse est lorsqu'une application établit une connexion avec votre base de données. Ainsi, peu importe le nombre de fois que vous supprimez cette connexion, l'application établit une autre connexion dès que vous arrêtez cette connexion, cette méthode fonctionne également dans ce scénario. et m'a sauvé beaucoup de temps et de tracas :) –

+0

J'apprécie votre réponse; Je suis désolé si mon commentaire impliquait autrement :) Juste un petit souci si, le fichier BAK doit être sur le serveur DB ou pourrais-je héberger dans le serveur de l'application ou tout autre endroit accessible? –

5

Appelez simplement KillAllProcesses. RollbackTransactionsImmediately est suffisant. Il tue toutes les sessions qui se trouvent dans cette base de données maintenant.

KillAllProcessesKillAllProcesses ne vous aide pas de toute façon car juste après avoir tué des sessions, un nouveau pourrait apparaître.

+0

I l'ai essayé aussi sans KillAllProcesses mais j'ai reçu le message d'erreur suivant: _RESTORE ne peut pas traiter la base de données 'AppDb' parce qu'elle est utilisée par cette session. Il est recommandé d'utiliser la base de données master lors de cette opération. RESTORE DATABASE se termine anormalement. –

+0

@RustyWizard OK, alors vous faites quelque chose pour avoir AppDB comme la base de données en cours comme suspecté par Vishal. Vérifiez ce qu'il a dit (base de données par défaut des utilisateurs). Connectez également SQL Profiler et parcourez toutes les instructions faites sur cette connexion pour voir s'il existe un 'USE AppDB'. – usr

+0

J'ai connecté un profileur SQL et j'ai essayé d'exécuter le script (sans la commande KillAllProcesses). Après avoir défini la base de données sur un seul utilisateur, la procédure sp sp_reset_connection est exécutée, suivie de l'opération de restauration. Il n'y a aucune application AppDb entre ces deux étapes. En outre, il utilise USE maître avant de définir la DB à un seul utilisateur. @usr –