如何使用Entity Framework快速删除表中的所有行?
我目前正在使用:
var rows = from o in dataDb.Table
           select o;
foreach (var row in rows)
{
    dataDb.Table.Remove(row);
}
dataDb.SaveChanges();但是,执行需要很长时间。
还有其他选择吗?
[TableName]不可移植。
                如何使用Entity Framework快速删除表中的所有行?
我目前正在使用:
var rows = from o in dataDb.Table
           select o;
foreach (var row in rows)
{
    dataDb.Table.Remove(row);
}
dataDb.SaveChanges();但是,执行需要很长时间。
还有其他选择吗?
[TableName]不可移植。
                Answers:
对于那些正在使用谷歌搜索并最终像我这样的人,这是您目前在EF5和EF6中的操作方式:
context.Database.ExecuteSqlCommand("TRUNCATE TABLE [TableName]");假设上下文是一个 System.Data.Entity.DbContext
[此处的转义特定于SQL Server,但TRUNCATE命令不是-它是ANSI SQL的一部分,因此可以在大多数SQL方言中使用(尽管不是SQLite)。
                    警告:以下内容仅适用于小型表(认为<1000行)
这是一个使用实体框架(不是SQL)删除行的解决方案,因此它不是特定于SQL Engine(R / DBM)的。
假设您正在这样做是为了进行测试或其他类似情况。要么
只需致电:
VotingContext.Votes.RemoveRange(VotingContext.Votes);假设这种情况:
public class VotingContext : DbContext
{
    public DbSet<Vote> Votes{get;set;}
    public DbSet<Poll> Polls{get;set;}
    public DbSet<Voter> Voters{get;set;}
    public DbSet<Candidacy> Candidates{get;set;}
}对于整理代码,您可以声明以下扩展方法:
public static class EntityExtensions
{
    public static void Clear<T>(this DbSet<T> dbSet) where T : class
    {
        dbSet.RemoveRange(dbSet);
    }
}然后,上面变成:
VotingContext.Votes.Clear();
VotingContext.Voters.Clear();
VotingContext.Candidacy.Clear();
VotingContext.Polls.Clear();
await VotingTestContext.SaveChangesAsync();最近,我使用了这种方法来为每个测试用例运行清理我的测试数据库(显然,这比每次从头开始重新创建数据库都快,尽管我没有检查生成的delete命令的形式)。
为什么会变慢?
因此,如果您要处理大量数据,则会杀死SQL Server进程(它将消耗所有内存),并且会破坏IIS进程,因为EF将以与SQL Server相同的方式缓存所有数据。如果您的表中包含大量数据,请不要使用此选项。
使用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]");TRUNCATE TABLE为DELETE FROM
                    var all = from c in dataDb.Table select c;
dataDb.Table.RemoveRange(all);
dataDb.SaveChanges();using (var context = new DataDb())
{
     var ctx = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)context).ObjectContext;
     ctx.ExecuteStoreCommand("DELETE FROM [TableName] WHERE Name= {0}", Name);
}要么
using (var context = new DataDb())
{
     context.Database.ExecuteSqlCommand("TRUNCATE TABLE [TableName]");
}Delete上IQueryable-我猜马尼什使用类似EntityFramework.Extended:github.com/loresoft/EntityFramework.Extended
                    .Delete是一个自定义扩展名,在首先发布答案的过程中,完全忘了提及此自定义的定义了.Delete。:)
                    您无需Foreach就可以做到
dataDB.Table.RemoveRange(dataDB.Table);
dataDB.SaveChanges();这将删除所有行
当我不得不处理一个特殊情况时,我遇到了这个问题:完全更新“叶”表中的内容(没有FK指向它)。这涉及删除所有行并放入新行信息,并且应该以事务方式完成(如果插入由于某种原因而失败,我不想以空表结尾)。
我尝试了该public static void Clear<T>(this DbSet<T> dbSet)方法,但是未插入新行。另一个缺点是整个过程很慢,因为行被逐行删除。
因此,我改用了TRUNCATE方法,因为它快得多而且也可以ROLLBACKable。它还会重置身份。
使用存储库模式的示例:
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失败)。
如果  
      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");
               }如果您希望清除整个数据库。
由于外键约束,表被截断的顺序很重要。这是暴力破解此序列的一种方法。
    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。
以下内容适用于SQLite数据库(使用实体框架)
似乎清除所有数据库表的最快方法是使用'context.Database.ExecuteSqlCommand(“ some 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()
删除所有记录。不要重置主索引,例如“ truncate”。
/// <summary>
/// SET - DELETE all record by table - no truncate - return deleted records
/// </summary>
public static int setListDelAllMYTABLE()
{
    // INIT
    int retObj = 0;
    using (MYDBEntities ctx = new MYDBEntities())
    {
        // GET - all record
        var tempAllRecord = ctx.MYTABLE.ToList();
        // RESET
        ctx.MYTABLE.RemoveRange(tempAllRecord);
        // SET - final save
        retObj += ctx.SaveChanges();
    }
    // RET
    return retObj;
}如果是MVC,则可以执行以下操作:
public async Task<IActionResult> DeleteAll()
{
    var list = await _context.YourClass.ToListAsync();
    _context.YourClass.RemoveRange(list);
    await _context.SaveChangesAsync();
    return RedirectToAction(nameof(Index));
}确保在尝试删除父级时,所有子级在删除时都将级联。或孩子有可为空的外键。
TRUNCATE担心外键约束。