代码之家  ›  专栏  ›  技术社区  ›  Richard Neil Ilagan

如何“停用”实体而不是使用NHibernate删除它?

  •  2
  • Richard Neil Ilagan  · 技术社区  · 14 年前

    所以我有实体。因此,NHibernate。我想做的是,只要我想“删除”实体,就只“停用”它们,而不是实际从数据库中删除它们。(只是因为我们不想真正从数据存储中删除记录)。

    我的所有实体都继承自 BaseEntity BaseEntity.Active 财产。

    我现在运行的是实体类映射文件中的如下内容:

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

    基本实体 继承任何子类化策略)。

    如你所见,这可能有点卑鄙。编码是 ,维护 可怕的 ,并且在同一个映射文件中声明两次表名只会让我感到不舒服。

    我之前所讨论的是是否可以实现一个事件侦听器;也许 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仍然会构建一个正确的DELETE SQL查询,它无论如何都会从数据存储中烧掉我的实体,而不是更新它,所以这只是浪费了automagic的精力。

    我该怎么办?

    2 回复  |  直到 13 年前
        1
  •  3
  •   Paco    14 年前

    您可以使用事件侦听器。您还必须将侦听器添加到配置中。

    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
  •  2
  •   Diego Mijelshon    14 年前

    很明显,您从未真正删除持久实体(大多数应用程序都是这样),因此不需要使用 Delete 方法,就因为它在那里。

    • Active
    • 删除 方法到您的基本实体
    • 你还可以, create a filter 避免加载“已删除”实体

    是的,那里

    如果使用基于代码+约定的映射方法(如ConfORM或Fluent),可以减轻一些负担。