我应该如何删除DbSet中的所有元素?

使用Entity Framework 4.3删除System.Data.Entity.DbSet中所有元素的最佳方法是什么?

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

(不开玩笑)

问题是EF不支持任何批处理命令,并且使用没有直接DML删除集合中的所有实体的唯一方法是:

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

或者,也许一点点便宜,以避免加载完整的实体:

 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(); 

但是,在这两种情况下,您必须加载所有实体或所有关键属性,并从集合中逐个删除实体。 而且,当你调用SaveChanges EF会发送n(=集合中的实体数)DELETE语句到数据库中,这个语句也会在数据库中逐个执行(在一个事务中)。

所以,直接的SQL显然更适合这个目的,因为你只需要一个DELETE语句。

这是另一种可以在代码中完成的方法。

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

要实际调用该方法并清除该集合:

 myDbContext.DeleteAll<MyPocoClassName>(); 

如果要删除所有元素而不写入任何SQL并只执行一个单一的Db调用

entity framework扩展库提供批量删除方法。

 context.Users.Delete(); 

由于接受的答案只提到下面的方法:

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

而是给它的替代品,我设法写一个方法,你可以用它来避免加载所有的实体,然后遍历它们,并使用ExecuteSqlCommand代替。

假设使用工作单元,上下文是DbContext:

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

第一块代码检索ExecuteSqlCommand方法中所需的表名。

用法:

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

没有必要打电话

 context.SaveChanges() 

如果您正在使用一个工作单元和通用存储库,则可能会发现以下内容

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

用法:

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

您可以通过使用直接查询来实现它:

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