TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #3216 1.57K
День 2686. #ЗаметкиНаПолях
Темпоральные таблицы в EF Core. Часть 1
Представьте, что вы создаёте платформу электронной коммерции. Клиент обращается в службу поддержки, утверждая, что его заказ был изменён без его согласия — адрес доставки изменился после оформления. Вашей операционной команде необходимо ответить на следующие вопросы:
- Как выглядел этот заказ на момент его оформления?
- Кто (или какой процесс) изменил адрес доставки и когда?
- Можно ли восстановить предыдущее состояние, не нарушая ссылочную целостность?

Наивный подход — добавить столбцы CreatedAt, UpdatedAt и ModifiedBy — показывает только дату последнего изменения. Вы не сохраняете историю. Самодельная таблица аудита изменений работает, но требует дисциплины:
- каждый разработчик должен помнить о необходимости записи в неё,
- каждый вызов SaveChanges() должен перехватываться.
Темпоральные таблицы SQL Server решают эту проблему на уровне ядра БД, а EF Core 6+ предоставляет к ним доступ через чистый, первоклассный API.

Что это?
Темпоральные таблицы автоматически поддерживают полную историю изменений строк. Ядро БД отслеживает:
- Текущее состояние каждой строки (основная таблица),
- Каждое предыдущее состояние с точным временным диапазоном, в течение которого оно было актуальным (таблица истории).
Два скрытых столбца периода datetime2 — обычно ValidFrom и ValidTo — определяют временной диапазон, в течение которого версия строки была актуальной. Они заполняются и управляются исключительно SQL Server, а не кодом приложения.

При обновлении строки старая версия перемещается в таблицу истории, при этом значение ValidTo устанавливается в текущую метку времени UTC. При удалении строки происходит то же самое — запись остаётся только в таблице истории.

Как это работает
INSERT
- В основную таблицу добавляется новая строка.
- ValidFrom устанавливается в текущее время транзакции.
- ValidTo устанавливается в 9999-12-31 23:59:59.9999999 («всё ещё актуально»).

UPDATE
SQL Server атомарно:
- Копирует текущую строку в таблицу истории, устанавливая значение ValidTo равным времени транзакции.
- Обновляет строку в основной таблице, устанавливая значение ValidFrom равным времени транзакции.

DELETE
- Текущая строка копируется в таблицу истории, устанавливая значение ValidTo равным текущему времени.
- Строка в основной таблице удаляется.

Все метки времени устанавливаются в UTC самим SQL Server. Ваше приложение не может их переопределить. Это фактически функция безопасности — она делает таблицу аудита изменений защищённой от несанкционированного изменения.

Продолжение следует…

Источник:
https://thecodeman.net/posts/temporal-tables-efcore-auditing-history
  • 👍 19
  • 👎 1
More from @netdeveloperdiary
  1. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  2. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  3. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  4. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  5. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →