我如何才能快速删除使用实体框架表中的所有行?
我目前使用:
var rows = from o in dataDb.Table
select o;
foreach (var row in rows)
{
dataDb.Table.Remove(row);
}
dataDb.SaveChanges();
但是,执行起来需要很长时间。
还有其他选择吗?
我如何才能快速删除使用实体框架表中的所有行?
我目前使用:
var rows = from o in dataDb.Table
select o;
foreach (var row in rows)
{
dataDb.Table.Remove(row);
}
dataDb.SaveChanges();
但是,执行起来需要很长时间。
还有其他选择吗?
当前回答
If
using(var db = new MyDbContext())
{
await db.Database.ExecuteSqlCommandAsync(@"TRUNCATE TABLE MyTable"););
}
原因
不能截断表'MyTable',因为它正被一个FOREIGN KEY约束引用。
我用这个:
using(var db = new MyDbContext())
{
await db.Database.ExecuteSqlCommandAsync(@"DELETE FROM MyTable WHERE ID != -1");
}
其他回答
Ef Core 3.1及以上
_context.Database.ExecuteSqlRaw($"TRUNCATE TABLE
{_context.Warehouse.EntityType.GetSchema()}.
{_context.Warehouse.EntityType.GetTableName()}");
仓库是dbSet
var all = from c in dataDb.Table select c;
dataDb.Table.RemoveRange(all);
dataDb.SaveChanges();
下面的工作在SQLite数据库(使用实体框架)。
似乎清除所有db表的最快方法是使用context.Database。ExecuteSqlCommand(“一些SQL”),正如上面的一些注释所突出显示的那样。在这里,我将展示如何重置表的“索引”计数。
context.Database.ExecuteSqlCommand("delete from TableA");
context.Database.ExecuteSqlCommand("delete from sqlite_sequence where name='TableA'");//resets the autoindex
context.Database.ExecuteSqlCommand("delete from TableB");
context.Database.ExecuteSqlCommand("delete from sqlite_sequence where name='TableB'");//resets the autoindex
context.Database.ExecuteSqlCommand("delete from TableC");
context.Database.ExecuteSqlCommand("delete from sqlite_sequence where name='TableC'");//resets the autoindex
重要的一点是,如果在表中使用外键,则必须首先在父表之前删除子表,因此在删除过程中表的顺序(层次结构)很重要,否则可能会发生SQLite异常。
注意:var context = new YourContext()
我在处理一个特殊情况时遇到了这个问题:完全更新“叶”表中的内容(没有指向它的fk)。这涉及到删除所有行并放入新行信息,这应该以事务方式完成(如果由于某种原因插入失败,我不想以空表结束)。
我已经尝试了公共静态void Clear<T>(此DbSet<T> DbSet)方法,但没有插入新行。另一个缺点是整个过程很慢,因为一行一行地删除。
因此,我已经切换到TRUNCATE方法,因为它更快,而且它也是可回滚的。它还重置标识。
使用存储库模式的示例:
public class Repository<T> : IRepository<T> where T : class, new()
{
private readonly IEfDbContext _context;
public void BulkInsert(IEnumerable<T> entities)
{
_context.BulkInsert(entities);
}
public void Truncate()
{
_context.Database.ExecuteSqlCommand($"TRUNCATE TABLE {typeof(T).Name}");
}
}
// usage
DataAccess.TheRepository.Truncate();
var toAddBulk = new List<EnvironmentXImportingSystem>();
// fill toAddBulk from source system
// ...
DataAccess.TheRepository.BulkInsert(toAddBulk);
DataAccess.SaveChanges();
当然,如前所述,由外键引用的表不能使用此解决方案(TRUNCATE失败)。
EF Core 7.0通过添加批量更新和删除语义一次性解决了这个问题:
await dataDB.Table.ExecuteDeleteAsync();
注意,此语法立即执行底层(SQL)命令从表中删除数据。它不需要跟踪实体、标记实体以便删除,也不需要等待UpdateDatabase对数据库执行事务。
还要注意,默认情况下,单个事务中不会包含多个ExecuteDelete和ExecuteUpdate命令。但是,可以使用DbContext事务api在事务中包装这些命令。