1

覆盖 DefaultDeleteEventListener 和 DefaultLoadEventListener 为使用 Nhibernate 实现软可删除提供了一个非常好的解决方案。

 public class SoftDeletableLoadEventListener : DefaultLoadEventListener
    {
        #region Non-public members

        protected override object DoLoad(LoadEvent @event,
            IEntityPersister persister, EntityKey keyToLoad,
            LoadType options)
        {
            object entity = base.DoLoad(@event, persister, keyToLoad, options);

            var softEntity = entity as ISoftDeletable;

            if (softEntity != null && softEntity.IsDeleted)
            {
                if (options == LoadEventListener.ImmediateLoad
                    || options == LoadEventListener.Load)
                {
                    string msg =
                        string.Format("Can not Load soft deleted entity typeof({0}) with Id {1} as it was deleted.",
                            softEntity.GetType().Name,
                            softEntity.Id);

                    throw new InvalidOperationException(msg);
                }
            }

            return entity;
        }

        #endregion
    }

正如 DefaultLoadEventListener 状态的摘要: 定义 NHibernate 用于加载实体以响应生成的加载事件的默认加载事件侦听器。

这意味着在执行 ExtraLazyLoading 时不应用过滤器,这会导致例如:已删除的实体被计数。是否有另一种方法可以在查询期间应用软可删除过滤器?有没有更好的方法,然后总是手动过滤添加限制?

4

1 回答 1

2

我已经用 nh 实现了软删除,但没有覆盖 DefaultLoadEventListener,但我认为我的集合加载策略也可以帮助你。您可以将 where 子句规范添加到您的集合中:

流畅的 NHibernate

.Override<Parent>(map =>
{
    map.HasMany<Child>(p => p.Children)
        .Where("IsDeleted = 0");
})

HBM.xml

<bag name="Children" where="IsDeleted = 0">
  <key>
    <column name="ParentID" />
  </key>
  <one-to-many class="Child" />
</bag>

编辑 刚刚从 nhibernate.info 中找到有关软删除的链接,该链接建议使用覆盖的 DefaultLoadEventListener 并使用 where 子句规范过滤选择。

于 2013-01-10T00:05:21.003 回答