Comment dois-je supprimer tous les éléments d’un DbSet?

Quelle est la meilleure façon de supprimer tous les éléments d’un System.Data.Entity.DbSet, avec Entity Framework 4.3?

dbContext.Database.ExecuteSqlCommand("delete from MyTable"); 

(Sans blague.)

Le problème est que EF ne prend en charge aucune commande par lot et que le seul moyen de supprimer toutes les entités d’un ensemble sans DML direct serait:

 foreach (var entity in dbContext.MyEntities) dbContext.MyEntities.Remove(entity); dbContext.SaveChanges(); 

Ou peut-être un peu moins cher pour éviter de charger des entités complètes:

 foreach (var id in dbContext.MyEntities.Select(e => e.Id)) { var entity = new MyEntity { Id = id }; dbContext.MyEntities.Attach(entity); dbContext.MyEntities.Remove(entity); } dbContext.SaveChanges(); 

Mais dans les deux cas, vous devez charger toutes les entités ou toutes les propriétés de clé et supprimer les entités une par une de l’ensemble. De plus, lorsque vous appelez SaveChanges EF enverra à la firebase database n (= nombre d’entités dans l’ensemble) des instructions DELETE qui seront également exécutées une par une dans la firebase database (en une seule transaction).

Ainsi, le SQL direct est clairement préférable à cette fin, car vous n’avez besoin que d’une seule instruction DELETE.

Voici une autre façon de le faire en code.

 public static class Extensions { public static void DeleteAll(this DbContext context) where T : class { foreach (var p in context.Set()) { context.Entry(p).State = EntityState.Deleted; } } } 

Pour appeler la méthode et effacer le jeu:

 myDbContext.DeleteAll(); 

Ancien message mais il existe maintenant une méthode RemoveRange:

  dbContext.MyEntities.RemoveRange(dbContext.MyEntities); dbContext.SaveChanges(); 

Si vous souhaitez supprimer tous les éléments sans écrire de code SQL et exécuter uniquement un appel Db unique

Entity Framework Extended Library propose une méthode de suppression par lot .

 context.Users.Delete(); 

Comme la réponse acceptée ne mentionne que la méthode ci-dessous:

 context.Database.ExecuteSqlCommand("delete from MyTable"); 

et donne plutôt des alternatives, j’ai réussi à écrire une méthode que vous pouvez utiliser pour éviter de charger toutes les entités, puis les parcourir en boucle et utiliser ExecuteSqlCommand à la place.

En supposant l’utilisation de l’unité de travail, où contexte est DbContext:

 using System.Data.Entity.Core.Objects; using System.Text.RegularExpressions; public void DeleteAll() { ObjectContext objectContext = ( (IObjectContextAdapter)context ).ObjectContext; ssortingng sql = objectContext.CreateObjectSet().ToTraceSsortingng(); Regex regex = new Regex( "FROM (?.*) AS" ); Match match = regex.Match( sql ); ssortingng tableName = match.Groups[ "table" ].Value; context.Database.ExecuteSqlCommand( ssortingng.Format( "delete from {0}", tableName ) ); }

Le premier bloc de code récupère le nom de la table nécessaire dans la méthode ExecuteSqlCommand .

Usage:

 using ( var context = new UnitOfWork() ) { context.MyRepository.DeleteAll(); } 

Il n’y a pas besoin d’appeler

 context.SaveChanges() 

Si vous travaillez avec une unité de travail et un référentiel générique, vous trouverez peut-être utile

 public virtual void DeleteWhere(Expression> filter = null, Func, IOrderedQueryable> orderBy = null, ssortingng includeProperties = "") { IQueryable query = dbSet; if (filter != null) { query = query.Where(filter); } foreach (var includeProperty in includeProperties.Split (new char[] { ',' }, SsortingngSplitOptions.RemoveEmptyEnsortinges)) { query = query.Include(includeProperty); } foreach (var entity in query) { context.Entry(entity).State = EntityState.Deleted; } } 

Usage:

 uow.myRepositoryName.DeleteWhere(u => u.RoomId == roomId); uow.Save(); 

Vous pouvez y parvenir en utilisant une requête directe:

  ent.Database.ExecuteSqlCommand("delete from tablename");