Как «деактивировать» сущность вместо ее удаления с помощью NHibernate? - PullRequest
2 голосов
/ 03 ноября 2010

Я не уверен, если это действительно тривиально, и я просто слишком усложняю вещи, но я думал об этом большую часть прошедшего часа или около того.

Итак, у меня есть сущности. Следовательно, NHibernate. Я хочу «деактивировать» сущности только тогда, когда я хочу «удалить» их, вместо того, чтобы фактически удалять их физически из базы данных. (Просто потому, что мы не хотим действительно удалять записи из нашего хранилища данных).

Все мои сущности наследуются от BaseEntity класса со свойством BaseEntity.Active.

Сейчас у меня работает что-то вроде следующего в файле отображения класса сущности:

<sql-delete>
UPDATE SomeEntityTable SET Active = 0 WHERE Id = ?
</sql-delete>

Это прекрасно работает, за исключением того, что мне придется вставить это, настроенное с именем таблицы, в каждый отдельный файл отображения HBM для каждой отдельной сущности (мы не реализуем наследование BaseEntity в любой стратегии подклассов).

Как видите, это может быть немного чертовски. Кодирование будет утомительным , обслуживание ужасным , и объявление имени таблицы дважды в одном и том же файле сопоставления будет просто неверным способом.

То, что я играл раньше, было то, смогу ли я реализовать прослушиватель событий; возможно OnPreDelete или что-то еще, и обновите свойство .Active сущности, например:

class BaseEventListener : IPreDeleteListener
{
    public bool OnPreDelete(PreDeleteEvent @event)
    {
        BaseEntity be = @event.Entity as BaseEntity;
        if (be != null) 
            be.Active = false;

        return false;
    }
}

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

Проблема в том, что я думаю, что NHibernate по-прежнему будет создавать правильный SQL-запрос DELETE, который в любом случае сожжет мою сущность из хранилища данных, а не обновит объект, так что это будет просто напрасным автоматическим усилием.

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

Ответы [ 2 ]

3 голосов
/ 03 ноября 2010

Вы можете использовать прослушиватель событий.Вы также должны добавить слушателя в конфигурацию.

public class SoftDeleteEventListener : DefaultDeleteEventListener
    {
        protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities)
        {
            var softDeletable = entity as BaseEntity;
            if (softDeletable != null)
            {
                softDeletable.Active = false;
            }
            else
            {
                base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities);
            }
        }
    }
2 голосов
/ 03 ноября 2010

Поскольку очевидно, что вы никогда не удаляете свои постоянные сущности (как в большинстве приложений), нет необходимости использовать метод Delete только потому, что он есть.

Альтернативный подход:

  • Объявите базовую сущность со свойством Active
  • . Установите значение false для случаев "удаления".Вы даже можете добавить Delete метод к вашей базовой сущности, который делает именно это
  • Вы можете дополнительно создать фильтр , чтобы избежать загрузки "удаленных" сущностей

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

Некоторые изнагрузка может быть уменьшена, если вы используете подход отображения на основе кода + соглашения, такой как ConfORM или Fluent.

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