Управление версиями объектов LINQ to SQL

Я пытаюсь создать класс LINQ to SQL, который представляет «последнюю» версию самого себя.

Прямо сейчас таблица, которую представляет эта сущность, имеет один автоматически увеличивающийся идентификатор, и я думал, что добавлю номер версии к первичному ключу. Я никогда не делал ничего подобного, поэтому я не уверен, что делать дальше. Я хотел бы иметь возможность абстрагироваться от идеи версии объекта от того, кто ее использует. Другими словами, у вас есть экземпляр этой сущности, который представляет самую последнюю версию, и всякий раз, когда какие-либо изменения отправляются, новая копия объекта сохраняется с увеличенным номером версии.

Как мне поступить с этим?

10.12.2008 15:24:11
2 ОТВЕТА
РЕШЕНИЕ

Если вы можете избежать истории, делайте. Это боль.

Если полная история неизбежна (регулируемые финансовые и медицинские данные или тому подобное), рассмотрите возможность добавления таблиц истории. Используйте триггер для «версии» в таблицах истории. Таким образом, вы не зависите от своего приложения, чтобы гарантировать, что версия записана - все вставки / обновления / удаления записываются независимо от источника.

Если ваше приложение должно взаимодействовать с историческими данными, убедитесь, что оно доступно только для чтения. Нет смысла фиксировать истории транзакций, если кто-то может просто изменить их.

Если вас беспокоит одновременное обновление, рассмотрите возможность использования метки времени изменения записи. Когда пользователь A и пользователь B просматривают запись в полдень, они получают метку времени записи. Когда пользователь А обновляет запись, его метка времени совпадает с меткой записи, поэтому обновление проходит, а метка времени также обновляется. Когда пользователь B обновляет запись пять минут спустя, его временная метка не соответствует записи, поэтому он предупреждается, что запись изменилась с момента его последнего просмотра. Может быть, он автоматически перезагружается ...

Что бы вы ни решили, я бы не стал смешивать текущие и исторические данные.


Запустить ресурсы по комментариям:

Ключами к триггеру аудита являются виртуальные таблицы «вставлены» и «удалены» . Эти таблицы содержат строки, на которые влияют INSERT, UPDATE или DELETE. Вы можете использовать их для аудита изменений. Что-то вроде:

CREATE TRIGGER tr_TheTrigger
ON [YourTable]
FOR INSERT, UPDATE, DELETE 
AS
    IF EXISTS(SELECT * FROM inserted)
    BEGIN
        --this is an insert or update
        --your actual action will vary but something like this
        INSERT INTO [YourTable_Audit]
            SELECT * FROM inserted
    END
    IF EXISTS(SELECT * FROM deleted)
    BEGIN
        --this is a delete, mark [YourTable_Audit] as required
    END
GO
5
23.05.2017 12:08:35
Я бы предпочел избежать этого, поверьте мне. К сожалению, по юридическим причинам мы должны отслеживать все изменения. Мне нужно будет взаимодействовать с историческими данными в приложении, но я предполагаю, что использование триггеров не должно исключать это, верно?
Jeremy Cantrell 10.12.2008 18:07:36
Ваше приложение не будет знать о триггерах, поэтому они не ограничивают вас. Это просто аккуратный способ обработки истории, даже если данные обновляются вне вашего приложения.
Corbin March 10.12.2008 19:14:16
Мне нравится этот подход. Можете ли вы указать мне некоторую информацию, которая относится к вашему предложению? Имейте в виду, что я никогда не использовал триггеры, и не уверен, как лучше это сделать.
Jeremy Cantrell 10.12.2008 20:03:05
Я использую триггерный подход, чтобы сохранить историю за некоторыми таблицами в течение пары лет, без проблем.
CGK 13.12.2011 14:57:36

Лучший способ - остановить и серьезно переосмыслить свой подход.

Если вы собираетесь хранить разные версии «объекта», то вам лучше сериализовать его в формат xml и сохранить его в столбце XML с полем для номера версии.

Есть серьезные соображения при попытке сохранить версионные данные на сервере sql, связанные с обслуживанием приложений.

ОБНОВЛЕНИЕ за комментарий:

Эти соображения включают в себя: невозможность удалить поле или изменить тип данных поля в будущих «версиях». Новые поля должны быть обнуляемыми или, по крайней мере, иметь значение по умолчанию, сохраненное для них в БД. Таким образом, вы не сможете использовать их в уникальном индексе или как часть первичных ключей.

Короче говоря, единственное, что может сделать ваше приложение - это расширить. При условии, что расширение может быть проигнорировано предыдущими уровнями кода.

Это классическая проблема обратной совместимости, с которой производители настольных программ боролись годами. И это причина, почему вы можете избежать этого.

0
10.12.2008 21:20:41
Да, я знаю об этих проблемах. Я искренне хочу избежать этого, но мы должны сделать это по юридическим причинам. Если бы им просто нужно было заархивировать данные в каком-то «тупом» формате, я бы просто сохранил их как гигантскую строку или что-то в этом роде, но приложению нужна интерактивность с историей.
Jeremy Cantrell 11.12.2008 05:06:30