我如何才能快速删除使用实体框架表中的所有行?
我目前使用:
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");
}
其他回答
var all = from c in dataDb.Table select c;
dataDb.Table.RemoveRange(all);
dataDb.SaveChanges();
EF Core 7.0通过添加批量更新和删除语义一次性解决了这个问题:
await dataDB.Table.ExecuteDeleteAsync();
注意,此语法立即执行底层(SQL)命令从表中删除数据。它不需要跟踪实体、标记实体以便删除,也不需要等待UpdateDatabase对数据库执行事务。
还要注意,默认情况下,单个事务中不会包含多个ExecuteDelete和ExecuteUpdate命令。但是,可以使用DbContext事务api在事务中包装这些命令。
删除所有记录。不要像“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;
}
下面是Ron的流行解决方案的一个变体,它通过利用另一个关于堆栈溢出的流行解决方案来确定实体框架类的底层表名,从而避免使用硬编码的字符串表名。
使用这些扩展方法,解决方案看起来像这样:
_dbContext.TruncateTable<TheTableName>();
(使用this.TruncateTable <…如果你在EF DBContext类或部分类文件中编辑代码)
这是扩展类:
public static class EntityFrameworkExtensions
{
private static string ParseTableNameFromSQL(string sql)
{
Regex regex = new Regex("FROM (?<table>.*) AS");
Match match = regex.Match(sql);
string table = match.Groups["table"].Value;
return table;
}
public static string GetTableName<T>(this IObjectContextAdapter context) where T : class =>
ParseTableNameFromSQL(context.ObjectContext.CreateObjectSet<T>().ToTraceString());
public static void TruncateTable<T>(this DbContext dbContext) where T : class =>
dbContext.Database.ExecuteSqlCommand($"TRUNCATE TABLE {dbContext.GetTableName<T>()}");
public static void DeleteAllTableRows<T>(this DbContext dbContext) where T : class =>
dbContext.Database.ExecuteSqlCommand($"DELETE FROM {dbContext.GetTableName<T>()}");
}
最后一个扩展方法DeleteAllTableRows是一个有用的替代方案,如果你的表不能被截断(例如,由于外键引用)-这仍然比实体框架RemoveAll替代方案快得多。
这在EF 5中正常工作:
YourEntityModel myEntities = new YourEntityModel();
var objCtx = ((IObjectContextAdapter)myEntities).ObjectContext;
objCtx.ExecuteStoreCommand("TRUNCATE TABLE [TableName]");