Управление версиями объектов LINQ to SQL - PullRequest
3 голосов
/ 10 декабря 2008

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

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

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

Ответы [ 2 ]

5 голосов
/ 10 декабря 2008

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

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

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

Если вас беспокоит одновременное обновление, рассмотрите возможность использования метки времени изменения записи. Когда пользователь 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
0 голосов
/ 10 декабря 2008

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...