63 votes

Supprimer toutes les entités dans Entity Framework

Je souhaite supprimer le contenu de toutes les tables (toutes les entités utilisant Entity Framework 4+). Comment cela peut-il être fait?

Merci James

54voto

Joel Mueller Points 14985

Cela fonctionnera beaucoup, beaucoup mieux que tout ce qui implique la suppression d'objets d'entité individuels, en supposant que la base de données sous-jacente est MSSQL.

 foreach (var tableName in listOfTableNames)
{
    context.ExecuteStoreCommand("TRUNCATE TABLE [" + tableName + "]");
}
 

Bien sûr, si vos tables ont des relations de clé étrangère, vous devez configurer votre liste de noms de table dans le bon ordre de manière à effacer les tables de clé étrangère avant d'effacer toute table à clé primaire sur laquelle elles pourraient dépendre.

17voto

Juste pour les fainéants, le code je suis venu moi-même lorsque je cherche le ansewr:

 public static void ClearDatabase<T>() where T : DbContext, new()
    {
        using (var context = new T())
        {
            var tableNames = context.Database.SqlQuery<string>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME NOT LIKE '%Migration%'").ToList();
            foreach (var tableName in tableNames)
            {
                context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableName));
            }

            context.SaveChanges();
        }
    }
 

Brève explication: je ne tronque pas les tables en raison du manque d'autorisations. Si ce n'est pas un problème pour vous, n'hésitez pas à le faire. La table __MigrationHistory est ignorée par l'instruction where.

MISE À JOUR: Après quelques recherches, j'ai trouvé une meilleure solution (moins agréable mais ne supprime que les colonnes requises):

 public static void ClearDatabase(DbContext context)
    {
        var objectContext = ((IObjectContextAdapter)context).ObjectContext;
        var entities = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace).BaseEntitySets;
        var method = objectContext.GetType().GetMethods().First(x => x.Name == "CreateObjectSet");
        var objectSets = entities.Select(x => method.MakeGenericMethod(Type.GetType(x.ElementType.FullName))).Select(x => x.Invoke(objectContext, null));
        var tableNames = objectSets.Select(objectSet => (objectSet.GetType().GetProperty("EntitySet").GetValue(objectSet, null) as EntitySet).Name).ToList();

        foreach (var tableName in tableNames)
        {
            context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableName));
        }

        context.SaveChanges();
    }
 

3voto

Peter Metz Points 137

Parcourez les tables avec un code ressemblant à ceci:

 context.GetType().GetProperties()
.Where(propertyInfo => propertyInfo.PropertyType == typeof(Table<>))
.Select(propertyInfo => propertyInfo.GetValue(context, null) as ITable).ToList()
.Foreach(table =>
{
    //code that deletes the actual tables records.
}
);
 

1voto

Kim Ki Won Points 303

tronqué n'a pas pu supprimer dans la clé étrangère.

alors j'ai fait la méthode d'extension pour DbContext.

l'utilisation est simple.

db.Truncates (); // toutes les suppressions de table.

db.Truncates ("Test1", "Test2"); // seulement la table "Test1, Test2" delete

 public static class DbContextExtension
{
    public static int Truncates(this DbContext db, params string[] tables)
    {
        List<string> target = new List<string>();
        int result = 0;

        if (tables == null || tables.Length == 0)
        {
            target = db.GetTableList();
        }
        else
        {
            target.AddRange(tables);
        }

        using (TransactionScope scope = new TransactionScope())
        {
            foreach (var table in target)
            {
                result += db.Database.ExecuteSqlCommand(string.Format("DELETE FROM  [{0}]", table));
                db.Database.ExecuteSqlCommand(string.Format("DBCC CHECKIDENT ([{0}], RESEED, 0)", table));
            }

            scope.Complete();
        }

        return result;
    }

    public static List<string> GetTableList(this DbContext db)
    {
        var type = db.GetType();

        return db.GetType().GetProperties()
            .Where(x => x.PropertyType.Name == "DbSet`1")
            .Select(x => x.Name).ToList();
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X