Entity Framework : Comment vider la base de données ?

De ORSWiki
Aller à : navigation, rechercher

Pour vider une base de données ayant des contraintes sur les tables, il faut supprimer les données dans un ordre logique. A défaut de connaître cet ordre logique, il suffit de parcourir toutes les tables, et de supprimer les enregistrements tant que cela est possible, et de recommencer tant qu'au moins une table n'a pas pu être vidée :


   Public Sub ViderBDD()
       Dim objectContext = DirectCast(context, Infrastructure.IObjectContextAdapter).ObjectContext
       Dim tables = objectContext.MetadataWorkspace.GetItems( _
           Of Core.Metadata.Edm.EntityType)(Core.Metadata.Edm.DataSpace.CSpace)
       Dim iNbTables% = tables.Count
       Dim iNumTentatives% = 0
   Recommencer:
       iNumTentatives += 1
       Dim bOk As Boolean = True
       Dim iNumTables% = 0
       For Each table In tables
           Dim sTable$ = table.Name
           m_msgDelegue.AfficherMsg("Vidage " & sTable & "...")
           Dim sMsgErr$ = ""
           If bViderTable(sTable, sMsgErr) Then
               iNumTables += 1
           Else
               Debug.WriteLine("Passe n°" & iNumTentatives & " : échec du vidage de : " & sTable & " :")
               Debug.WriteLine(sMsgErr)
               bOk = False
           End If
       Next
       If Not bOk Then
           Debug.WriteLine("Tentative n°" & iNumTentatives & " : " & iNumTables & "/" & iNbTables)
           GoTo Recommencer
       End If
       m_msgDelegue.AfficherMsg("Terminé.")
       MsgBox("Vidage de la base : succès !", MsgBoxStyle.Exclamation, m_sTitreMsg)
   End Sub
   ' Attribut pour éviter que l'IDE s'interrompt en cas d'exception
   <System.Diagnostics.DebuggerStepThrough()> _
   Private Function bViderTable(sTable$, ByRef sMsgErr$) As Boolean
       Try
           Dim sSQL$ = String.Format("DELETE FROM {0}", sTable)
           context.Database.ExecuteSqlCommand(sSQL)
           Return True
       Catch ex As Exception
           sMsgErr = ex.Message
           Return False
       End Try
   End Function


Attention, l'instruction Truncate est plus performante que Delete From, mais elle n'est pas toujours possible selon les contraintes des tables (on peut établir une liste des tables pour lesquelles on doit faire Delete From à la place de Truncate, si l'on veut optimiser).


Note : il arrive parfois qu'une table ne puisse être vidée à la suite d'un problème plus rare (corruption de la base de données ?). Dans ce cas, il faudrait traiter précisément l'exception retournée, sinon ce code partira en boucle infinie. La solution est alors de vider la table récalcitrante via phpmyadmin par exemple.


Si vous avez besoin de ce code pour supprimer les données, vous aurez sûrement aussi des problèmes pour recharger votre base de données, car il faudra là aussi respecter le même ordre logique. Vous pouvez tester l'utilitaire MySqlBackup pour contrôler l'ordre de sauvegarde et de restauration des données, en ignorant les éventuels changement de structure et en ignorant les exceptions qui pourraient en résulter (mb.ExportInfo.ExportTableStructure = False et mb.ImportInfo.IgnoreSqlError = True).