Entity Framework : Comment vider la base de données ?
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).