我如何才能快速删除使用实体框架表中的所有行?

我目前使用:

var rows = from o in dataDb.Table
           select o;
foreach (var row in rows)
{
    dataDb.Table.Remove(row);
}
dataDb.SaveChanges();

但是,执行起来需要很长时间。

还有其他选择吗?


当前回答

如果您希望清除整个数据库。

由于外键的限制,截断表的顺序很重要。这是一种强行执行这个序列的方法。

    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)
            {
                foreach (var t in tableNames)
                {
                    try
                    {

                        if (context.Database.ExecuteSqlCommand(string.Format("TRUNCATE TABLE [{0}]", tableName)) == 1)
                            break;

                    }
                    catch (Exception ex)
                    {

                    }
                }
            }

            context.SaveChanges();
        }
    }

用法:

ClearDatabase<ApplicationDbContext>();

记住在此之后重新实例化DbContext。

其他回答

使用SQL的TRUNCATE TABLE命令将是最快的,因为它操作的是表,而不是单个行。

dataDb.ExecuteStoreCommand("TRUNCATE TABLE [Table]");

假设dataDb是一个DbContext(而不是ObjectContext),你可以包装它并像这样使用方法:

var objCtx = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)dataDb).ObjectContext;
objCtx.ExecuteStoreCommand("TRUNCATE TABLE [Table]");

没有Foreach你也能做到

dataDB.Table.RemoveRange(dataDB.Table);
dataDB.SaveChanges();

这将删除所有行

context.TableName.RemoveRange(context.TableName);
context.SaveChanges();

Ef Core 3.1及以上

 _context.Database.ExecuteSqlRaw($"TRUNCATE TABLE 
     {_context.Warehouse.EntityType.GetSchema()}. 
     {_context.Warehouse.EntityType.GetTableName()}");

仓库是dbSet

EF Core 7.0通过添加批量更新和删除语义一次性解决了这个问题:

await dataDB.Table.ExecuteDeleteAsync();

注意,此语法立即执行底层(SQL)命令从表中删除数据。它不需要跟踪实体、标记实体以便删除,也不需要等待UpdateDatabase对数据库执行事务。

还要注意,默认情况下,单个事务中不会包含多个ExecuteDelete和ExecuteUpdate命令。但是,可以使用DbContext事务api在事务中包装这些命令。