Quiero eliminar el contenido de todas las tablas (todas las entidades) utilizando Entity Framework 4+. ¿Cómo puede hacerse esto?Eliminar todas las entidades en Entity Framework
Respuesta
Esto realizará mucho, mucho mejor que cualquier cosa que implica la supresión de objetos de entidad individuales, suponiendo que la base de datos subyacente es MSSQL.
foreach (var tableName in listOfTableNames)
{
context.ExecuteStoreCommand("TRUNCATE TABLE [" + tableName + "]");
}
Por supuesto, si las tablas tienen relaciones de clave externa, que necesitará para configurar la lista de nombres de tabla en el orden correcto para que clara tablas de clave externa antes de borrar cualquier-clave primaria tablas de las que podrían depender.
Iterar a través de las mesas con un código de algo como esto:
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.
}
);
Solo para los perezosos, código que se acercó a mí mismo en la búsqueda de la respuesta:
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();
}
}
Breve explicación: yo no truncar tablas debido a la falta de permisos, si no es un problema para usted, siéntete libre de hacerlo. La tabla __MigrationHistory es ignorada por la instrucción where.
ACTUALIZACIÓN: Después de algunas investigaciones que se me ocurrió mejor solución (no tan agradable, pero sólo elimina columnas requeridas):
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();
}
Una modificación más: use la función de reflexión para buscar los nombres de las tablas. –
Esta solución no funcionará cuando el tipo de datos PONO se declare en algún otro ensamblaje (la línea 'Type.GetType' falla). De lo contrario, buena solución! –
truncado no pudo eliminar dentro de clave externa.
luego hice el método de extensión para DbContext.
uso es simple.
db.Truncates(); // todas las tablas se eliminan.
db.Truncates ("Prueba1", "Prueba2"); // única "Prueba1, Test2" mesa de borrar
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();
}
}
¡Muy bien! No pude hacer que TRUNCATE funcionara con una clave externa, incluso al guardar primero al padre y eliminar el contexto. –
me gustaría tratar de mejorar la gran respuesta de @Wojciech Markowski.
Si usted es perezoso como yo, y no desea comprobar si hay restricciones de claves foráneas, puede utilizar este método:
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();
}
método ClearDatabase va sobre la lista de tablas y limpiarlos. si se encuentra la restricción FK, capture la excepción y pase a la siguiente tabla. al final se eliminarán todas las tablas.
Por otra parte, si no le importa perder todas las restricciones FK, puede desactivar todos ellos por la línea:
context.Database.ExecuteSqlCommand("EXEC sp_MSforeachtable @command1 = 'ALTER TABLE ? NOCHECK CONSTRAINT all'");
Una cosa más: Si desea eliminar todas las tablas y no simplemente eliminarlas, a continuación, sustituya la línea:
context.Database.ExecuteSqlCommand(string.Format("DELETE FROM {0}", tableNames.ElementAt(i % tableNames.Count)));
con:
context.Database.ExecuteSqlCommand(string.Format("DROP TABLE {0}", tableNames.ElementAt(i % tableNames.Count)));
Personalmente comprobé esta respuesta en Entity Framework 6 con migración de código primero.
EDIT: mejor versión:
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);
}
}
}
la sentencia if en cheques de bloque de captura si alcancé el último índice de la lista de tablas sin borrar cualquier tabla. En ese caso, en lugar de ir en un bucle infinito, lanza una excepción y sale del.
Para EF 6:
DbSet<Entity>.RemoveRange(DbSet<Entity>);
Esto sigue siendo actual para EF Core. – Grimley
- 1. ¿Cómo eliminar referencias circulares en Entity Framework?
- 2. Entity Framework - carga ansiosa de entidades relacionadas
- 3. Cómo actualizar entidades relacionadas en Entity Framework
- 4. Entity Framework en eliminar cascada
- 5. Cargando entidades anidadas/colecciones con Entity Framework
- 6. ¿Puedo abstraer Entity Framework de mis Entidades?
- 7. Entity Framework - Ansioso de cargar entidades relacionadas
- 8. Entity Framework - Comenzar de nuevo - Deshacer/Revertir todas las migraciones
- 9. Impedir Entity Framework para adjuntar entidades automáticamente
- 10. Entity framework - Todas las tablas en un solo archivo edmx
- 11. Eliminar en cascada en Entity Framework
- 12. ado.net entity framework eliminar filas
- 13. Soporte de raíz agregada en Entity Framework
- 14. Entity Framework Eliminar todo en enviar
- 15. Cómo contar entidades asociadas sin recuperarlas en Entity Framework
- 16. Entity Framework: entidades de asociación de problemas con campo nullable
- 17. Cómo guardar entidades separadas (nuevas + modificadas) separadas en Entity Framework?
- 18. error al usar interfaces para entidades de Entity Framework (4.2)
- 19. SqlBulkCopy y Entity Framework
- 20. niño eliminar objetos de Entity Framework
- 21. Entity Framework: compruebe todas las relaciones de una entidad para el uso de la clave externa
- 22. Entity Framework - Cómo debería instanciar mi objeto "Entidades"
- 23. ¿Usar entidades de Entity Framework como objetos comerciales?
- 24. Json.Net caracteres inesperados ("\") al serializar mis entidades (Entity framework)
- 25. ¿Por qué no Entity Framework consultas devuelven entidades no guardados
- 26. ¿Puedo deshabilitar las relaciones automáticas en Entity Framework Code First?
- 27. ¿Cómo reutilizar las proyecciones en Entity Framework?
- 28. Descripción de las transacciones en Entity Framework
- 29. Eliminar todas las imágenes
- 30. Entity Framework Split Table Delete
Asegúrese de desechar y renovar su contexto de datos, sin embargo! – Vinzz
Una ventaja de DELETE en comparación con TRUNCATE: para ELIMINAR el rol db_datawriter es suficiente, ¡para TRUNCATE no lo es! Es por eso que prefiero ELIMINAR siempre que el rendimiento sea suficiente. – Tillito
en EF5 que necesitan ser así: context.Database.ExecuteSqlCommand ("TRUNCATE TABLE [" + tableName + "]"); que vino de [liere] (http://stackoverflow.com/questions/13857242/where-is-executestorecommand-in-entity-framework-5) – oCcSking