День 1165. #ЧтоНовенького
Темпоральные Таблицы SQL Server в EF Core 6.0
Темпоральные таблицы SQL Server автоматически отслеживают все данные, когда-либо хранившиеся в таблице, даже после того, как эти данные были обновлены или удалены. Это достигается за счёт создания параллельной «таблицы истории», в которой сохраняются исторические данные с временными метками всякий раз, когда в основную таблицу вносятся изменения. Это позволяет запрашивать исторические данные, например, для аудита, или восстанавливать их, например, после случайного изменения или удаления.
EF Core 6.0 поддерживает:
- Создание темпоральных таблиц с помощью миграций EF Core
- Преобразование существующих таблиц во темпоральные таблицы, опять же с использованием миграций
- Запросы исторических данных
- Восстановление данных с какого-то момента в прошлом
Пример использования темпоральных таблиц можно найти на GitHub.
Настройка темпоральной таблицы
Типы сущностей сопоставляются с темпоральными таблицами в OnModelCreating с помощью метода IsTemporal:
protected override void OnModelCreating(ModelBuilder builder)
{
builder
.Entity<Product>()
.ToTable("Products", b => b.IsTemporal());
}
Затем миграции EF Core либо создадут эти таблицы как темпоральные, либо, если таблицы уже существуют, они будут преобразованы в темпоральные. Миграция добавляет два скрытых столбца datetime2 с именами PeriodStart и PeriodEnd. Они представляют диапазон времени, в течение которого существовали эти данные в строке. Эти столбцы сопоставляются с теневыми свойствами в модели EF Core, что позволяет использовать их в запросах.
Запрос исторических данных
В большинстве случаев темпоральные таблицы используются точно так же, как и любые другие. Объекты добавляются, запрашиваются, обновляются и удаляются обычным способом.
EF Core поддерживает несколько операторов запросов к темпоральным таблицам:
- TemporalAsOf: возвращает строки, которые были активны в указанное время UTC. Это одна строка из таблицы истории для данного первичного ключа.
- TemporalAll: возвращает все строки в исторических данных. Обычно это много строк из таблицы истории для данного первичного ключа.
- TemporalFromTo: возвращает все строки, которые были активны между двумя заданными значениями времени UTC. Это может быть много строк из таблицы истории для данного первичного ключа.
- TemporalBetween: то же, что и TemporalFromTo, за исключением того, что включаются только строки, которые стали активными с начала периода.
- TemporalContainedIn: возвращает все строки, которые начали быть активными и закончили быть активными между двумя заданными значениями времени UTC. Это может быть много строк из таблицы истории для данного первичного ключа.
Например, следующий запрос вернёт цены продукта между двумя датами from и to:
var prices = context.Products
.TemporalBetween(from, to)
.OrderBy(p =>
EF.Property<DateTime>(p, "PeriodStart"))
.Where(p => p.Name == name)
.Select(p =>
new {
Product = p,
PeriodStart =
EF.Property<DateTime>(p, "PeriodStart"),
PeriodEnd =
EF.Property<DateTime>(p, "PeriodEnd")
})
.ToList();
Источник: devblogs.microsoft.com/dotnet/…core-6-0