Я сделал что-то подобное. У меня есть таблица с именем LoggableEntity, которая содержит: ID (PK).
Тогда у меня есть таблица EntityLog, которая содержит информацию об изменениях, внесенных в loggableentity (запись): ID (PK), EntityID (от FK до LoggableEntity.ID), ChangedBy (имя пользователя, который внес изменение), ChangedAt (smalldatetime, когда изменение произошло), Тип (перечисление: Создать, Удалить, Обновить), Детали (поле с записью, что изменилось - может быть XML с сериализованными деталями).
Теперь каждая таблица (сущность), которую я хочу отслеживать, «получена» из таблицы LoggableEntity, что означает, например, что у Customer есть таблица FK для таблицы LoggableEntity.
Теперь мой код DAL заботится о заполнении таблицы EntityLog каждый раз, когда вносятся изменения в запись клиента. Каждый раз, когда он видит, что класс сущности является loggableentity, он добавляет новую запись изменения в таблицу entitylog.
Итак, вот моя структура таблицы:
+------------------+ +------------------+
| LoggableEntity | | EntityLog |
| ---------------- | | ---------------- |
| (PK) ID | <--+ | (PK) ID |
+------------------+ +----- | (FK) LoggableID |
^ | ... |
| +------------------+
+------------------+
| Customer |
| ---------------- |
| (PK) ID |
| (FK) LoggableID |
| ... |
+------------------+