2013-01-07 2 views
1

DefaultDeleteEventListener 및 DefaultLoadEventListener를 대체하면 Nhibernate를 사용하여 소프트 삭제 가능 항목을 구현하는 정말 좋은 솔루션을 제공합니다. 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 
    } 

상태 : 가 발생로드 이벤트에 따라 에 로딩 엔티티 NHibernate에 사용되는 기본로드 이벤트 리스너를 정의합니다.

이것은 ExtraLazyLoading을 수행 할 때 필터가 적용되지 않음을 의미합니다. 즉, 삭제 된 항목 수가 계산됩니다. 쿼리 중에 소프트 삭제 가능 필터를 적용하는 다른 방법이 있습니까? 더 나은 방법이 있습니까?

답변

2

DefaultLoadEventListener를 재정의하지 않고 nh로 소프트 삭제를 구현했지만 컬렉션로드 전략이 도움이 될 것으로 생각합니다. 당신은 당신의 컬렉션에 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> 

단지에서 소프트 삭제에 대해이 link을 발견 편집 재정의 된 DefaultLoadEvent를 사용하도록 권장하는 nhibernate.info Where 절 지정을 사용하여 select를 청취하고 필터링합니다.

+0

고맙습니다. 더 일반적인 솔루션을 찾고 싶습니다. –

+0

"보다 일반적인"으로, 각 컬렉션을 표시하는 대신 1 곳에서 수정하려고한다고 상상해보십시오. Where 절 사양? –

+0

예, 그것은 가장 깨끗한 방법 일 것입니다. 나는 코드 컨벤션을 사용하여 컬렉션의 매핑에 항상 Where() 절을 추가하는 것이 약간 번거롭다 고 생각한다. –