使用Entity Framework 4.3删除System.Data.Entity.DbSet中的所有元素的最佳方法是什么?
Answers:
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语句,这些语句也将在DB中一次(一次交易)被执行。
因此,直接SQL显然是首选,因为您只需要一个DELETE语句。
旧帖子,但是现在有一个RemoveRange方法:
dbContext.MyEntities.RemoveRange(dbContext.MyEntities);
dbContext.SaveChanges();
由于接受的答案仅提及以下方法:
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();
SaveChanges
后dbContext.Database.ExecuteSqlCommand
?