我想使用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