我想使用Entity Framework 4+删除所有表(所有实体)的内容。如何才能做到这一点?删除Entity Framework中的所有实体
回答
这将执行很多,比涉及删除各个实体对象的东西多更好,假设底层数据库是MSSQL。
foreach (var tableName in listOfTableNames)
{
context.ExecuteStoreCommand("TRUNCATE TABLE [" + tableName + "]");
}
当然,如果你的表有外键关系,你需要设置你的表名的列表以正确的顺序,让你清晰外键的表,你明确之前任何主键他们可能依赖的表格。
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)
{
context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableName));
}
context.SaveChanges();
}
}
简短说明:
迭代通过与代码像这样的表:
context.GetType().GetProperties()
.Where(propertyInfo => propertyInfo.PropertyType == typeof(Table<>))
.Select(propertyInfo => propertyInfo.GetValue(context, null) as ITable).ToList()
.Foreach(table =>
{
//code that deletes the actual tables records.
}
);
只是懒惰的人,寻找答案时的代码,我想出了自己 我不截断表由于缺乏权限,如果这不是你的问题,随时可以这样做。 where语句忽略表__MigrationHistory。
更新:一些研究,我想出了更好的解决方案(不是很好,但仅删除所需的列)后:
public static void ClearDatabase(DbContext context)
{
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var entities = objectContext.MetadataWorkspace.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace).BaseEntitySets;
var method = objectContext.GetType().GetMethods().First(x => x.Name == "CreateObjectSet");
var objectSets = entities.Select(x => method.MakeGenericMethod(Type.GetType(x.ElementType.FullName))).Select(x => x.Invoke(objectContext, null));
var tableNames = objectSets.Select(objectSet => (objectSet.GetType().GetProperty("EntitySet").GetValue(objectSet, null) as EntitySet).Name).ToList();
foreach (var tableName in tableNames)
{
context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableName));
}
context.SaveChanges();
}
再一次修改: 使用反射来查找表名称。 – 2012-11-07 17:08:25
当某个其他程序集中声明了PONO数据类型('Type.GetType'行失败)时,此解决方案将不起作用。否则,好的解决方案! – 2014-05-17 18:18:40
截断不能外键内删除。
然后我做了DbContext的扩展方法。
用法很简单。
db.Truncates(); //所有表删除。
db.Truncates(“Test1”,“Test2”); //只 “的Test1,Test2的” 表中删除
public static class DbContextExtension
{
public static int Truncates(this DbContext db, params string[] tables)
{
List<string> target = new List<string>();
int result = 0;
if (tables == null || tables.Length == 0)
{
target = db.GetTableList();
}
else
{
target.AddRange(tables);
}
using (TransactionScope scope = new TransactionScope())
{
foreach (var table in target)
{
result += db.Database.ExecuteSqlCommand(string.Format("DELETE FROM [{0}]", table));
db.Database.ExecuteSqlCommand(string.Format("DBCC CHECKIDENT ([{0}], RESEED, 0)", table));
}
scope.Complete();
}
return result;
}
public static List<string> GetTableList(this DbContext db)
{
var type = db.GetType();
return db.GetType().GetProperties()
.Where(x => x.PropertyType.Name == "DbSet`1")
.Select(x => x.Name).ToList();
}
}
非常好!即使先保存父项并处理上下文,我也无法使用外键来使用TRUNCATE。 – 2015-01-13 12:51:49
我想设法改善@Wojciech Markowski伟大的答案。
如果你是懒惰和我一样,不想检查外键约束, 你可以使用这个方法:
private void ClearDatabase(TContext context)
{
// disable all foreign keys
//context.Database.ExecuteSqlCommand("EXEC sp_MSforeachtable @command1 = 'ALTER TABLE ? NOCHECK CONSTRAINT all'");
List<string> tableNames = context.Database.SqlQuery<string>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME NOT LIKE '%Migration%'").ToList();
for (int i = 0; tableNames.Count>0; i++)
{
try
{
context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableNames.ElementAt(i % tableNames.Count)));
tableNames.RemoveAt(i % tableNames.Count);
i = 0;
}
catch { } // ignore errors as these are expected due to linked foreign key data
}
context.SaveChanges();
}
ClearDatabase方法越过表的列表,并清除它们。如果找到FK约束,则捕获异常并转到下一个表。 最后所有表格都将被删除。
而且,如果你不介意失去所有的FK约束,你可以通过行禁用所有的人:
context.Database.ExecuteSqlCommand("EXEC sp_MSforeachtable @command1 = 'ALTER TABLE ? NOCHECK CONSTRAINT all'");
还有一件事: 如果你想删除所有表和未只是清除它们,然后再更换行:
context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableNames.ElementAt(i % tableNames.Count)));
有:
context.Database.ExecuteSqlCommand(string.Format("DROP TABLE {0}", tableNames.ElementAt(i % tableNames.Count)));
我亲自在代码优先的迁移中在Entity Framework 6上检查了这个答案。
编辑:更好的版本:
private void ClearDatabase(MrSaleDbContext context)
{
//Optional: disable all foreign keys (db-schema will be loosed).
//context.Database.ExecuteSqlCommand("EXEC sp_MSforeachtable @command1 = 'ALTER TABLE ? NOCHECK CONSTRAINT all'");
List<string> tableNames = context.Database.SqlQuery<string>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME NOT LIKE '%Migration%' AND TABLE_NAME NOT LIKE 'AspNet%'").ToList();
for (int i = 0; tableNames.Count > 0; i++)
{
try
{
//To delete all tables and not just clean them from data, replace "DELETE FROM {0}" in "DROP TABLE {0}":
context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableNames.ElementAt(i % tableNames.Count)));
tableNames.RemoveAt(i % tableNames.Count);
i = -1; //flag: a table was removed. in the next iteration i++ will be the 0 index.
}
catch (System.Data.SqlClient.SqlException e) // ignore errors as these are expected due to linked foreign key data
{
if ((i % tableNames.Count) == (tableNames.Count - 1))
{
//end of tables-list without any success to delete any table, then exit with exception:
throw new System.Data.DataException("Unable to clear all relevant tables in database (foriegn key constraint ?). See inner-exception for more details.", e);
}
}
}
if语句中catch块检查自己是否达到了表列表的最后一个索引,而不删除任何表。在这种情况下,不要进入无限循环,而是抛出异常并退出for。
- 1. 删除实体并删除Entity框架上的关系
- 2. 删除实体框架中的所有相关实体
- 3. 如何获得Entity Framework 6.1中所有实体关系的列表?
- 4. 在Entity Framework中自定义实体实体化6
- 5. 如何删除所有JPA实体?
- 6. 使用Entity Framework 5实体映射实体代码
- 7. 辅助函数删除/删除所有实体数据,EF
- 8. 如何删除由Entity Framework生成的sql-code中的引号?
- 9. 最佳实践 - ASP.NET/Entity Framework
- 10. 在Entity Framework中创建要插入的实体对象6
- 11. 如何将2+表映射到.NET Entity Framework中的实体?
- 12. 如何在Entity Framework中获取实体的原始值?
- 13. 在.NET Entity Framework中的上下文之间移动实体3.5
- 14. 将多个表映射到Entity Framework中的单个实体
- 15. 如何克隆Entity Framework Core中的实体?
- 16. 将Entity Framework中的表拆分为多个实体
- 17. 在Entity Framework中保存实体的通用方法
- 18. 为什么Entity Framework(Core)删除Add()操作中的旧记录?
- 19. 如何用Entity Framework(EF6)删除Asp.Net MVC 5中的ApplicationUser?
- 20. AUCTeX:删除所有字体
- 21. Symfony 2,createForm删除Entity实体的关系
- 22. 在Entity Framework中将多行组合到一个实体中4.1
- 23. 如何删除GAE中所有名称空间中的所有实体?
- 24. 如何对eclipselink中的所有实体进行软删除(逻辑删除)
- 25. 实体框架3.5sp1删除关联表中的所有内容?
- 26. 如何删除Azure表中的所有实体?
- 27. 实体框架。删除表中的所有行
- 28. 如何从ManagedObjectContext中删除给定实体的所有对象
- 29. 删除核心数据中的所有未提交实体
- 30. 从.net项目中删除Entity Framework时可以删除哪些程序集?
一定要部署和更新数据方面,尽管! – Vinzz 2012-06-12 11:57:09
与TRUNCATE相比,DELETE的一个优点是:对于删除角色db_datawriter就足够了,对于TRUNCATE而言不是!这就是为什么我喜欢DELETE,只要性能足够。需要如下所示的EF5中的 – Tillito 2012-08-23 13:24:15
:context.Database.ExecuteSqlCommand(“TRUNCATE TABLE [”+ tableName +“]”);来自[野兔](http://stackoverflow.com/questions/13857242/where-is-executestorecommand-in-entity-framework-5) – oCcSking 2013-05-20 15:06:47