using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
namespace Pf2eModel;
///
/// Класс, обеспецивающий общий способ для отчистки данных таблиц.
///
/// Источник: https://www.codeproject.com/Articles/5339402/Delete-All-Rows-in-Entity-Framework-Core-6
///
public static class EfCleanHelper
{
///
/// Определение полного названия таблицы по служебному классу.
///
/// Служебный класс, определяющий таблицу базы данных.
/// Схема таблицы по умолчанию ("public" для PostgresSQL)
///
private static string GetName(IEntityType entityType, string defaultSchemaName = "public")
{
object? schema = entityType.FindAnnotation("Relational:Schema")?.Value;
string tableName =
entityType.GetAnnotation("Relational:TableName").Value?.ToString()
?? throw new($"Не могу определить название таблицы для типа {entityType}");
string schemaName = schema?.ToString() ?? defaultSchemaName;
string name = $"\"{schemaName}\".\"{tableName}\"";
return name;
}
///
/// Определение полного названия таблицы по типу сущности.
///
/// Тип искомой сущности.
/// Контекст, в котором производится поиск таблицы.
/// Строковое представление названия таблицы.
public static string TableName(DbContext dbContext)
where T : class
{
IEntityType entityType =
dbContext.Model.FindEntityType(typeof(T))
?? throw new($"Не могу определить название таблицы для класса {typeof(T)}");
return GetName(entityType);
}
///
/// Определение полного названия таблицы по типу сущности.
///
/// Тип искомой сущности.
/// CLR-представление таблицы, название которой требуется определить.
/// Строковое представление названия таблицы.
public static string TableName(DbSet dbSet)
where T : class
{
IEntityType entityType = dbSet.EntityType;
return GetName(entityType);
}
///
/// Отчистка содержимого таблицы.
///
/// Тип сущности, таблицу которой необходимо отчистить.
/// CLR-представление таблицы, которую требуется отчистить.
/// Строковое представление выполненной SQL-команды.
public static string Truncate(this DbSet dbSet)
where T : class
{
string cmd = $"TRUNCATE TABLE {TableName(dbSet)} RESTART IDENTITY CASCADE;";
DbContext context = dbSet.GetService().Context;
context.Database.ExecuteSqlRaw(cmd);
return cmd;
}
///
/// Получение SQL-команды отчистки содержимого всех таблиц базы данных.
///
/// Контекст базы данных, в которой необходимо отчистить все строки.
/// Строковое представление выполненных SQL-команды.
public static string TruncateAll(this DbContext context)
{
IEnumerable tables = context.Model.GetEntityTypes();
List cmdList = [];
foreach (IEntityType entityType in tables)
{
string cmd = $"TRUNCATE TABLE {GetName(entityType)} RESTART IDENTITY CASCADE;";
context.Database.ExecuteSqlRaw(cmd);
cmdList.Add(cmd);
}
return string.Join('\n', cmdList);
}
}