我如何才能快速删除使用实体框架表中的所有行?
我目前使用:
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();
但是,执行起来需要很长时间。
还有其他选择吗?
当前回答
下面是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]");
使用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]");
下面是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替代方案快得多。
确保当你试图删除父级时,所有的子级将在删除时级联。或者子节点的外键为空。
这里有几个问题,几乎所有的答案:
1]硬编码的sql。括号是否适用于所有数据库引擎? 2]实体框架Remove和RemoveRange调用。这会将所有实体加载到受操作影响的内存中。呵。 3]截表。与外键引用中断,可能无法跨所有数据库引擎工作。
使用https://entityframework-plus.net/,他们处理跨数据库平台的事情,将删除转换为正确的sql语句,并且不将实体加载到内存中,并且该库是免费的开源的。
免责声明:我不隶属于nuget包。他们确实提供了付费版本,功能甚至更多。