2

나는 엔티티가 두 번째 수준의 캐시를 연결할 때까지 따라서 Cacheable() 줄의 주석을 제거하면 예외가 발생합니다.NHibernate에 2 레벨의 캐시

메시지 : 값은 null 일 수 없습니다. 매개 변수 이름 :

at NHibernate.Transform.AliasedTupleSubsetResultTransformer.IncludeInTransform(String[] aliases, Int32 tupleLength) 
    at NHibernate.Transform.CacheableResultTransformer.Create(ITupleSubsetResultTransformer transformer, String[] aliases, Boolean[] includeInTuple) 
    at NHibernate.Loader.Loader.GenerateQueryKey(ISessionImplementor session, QueryParameters queryParameters) 
    at NHibernate.Loader.Loader.ListUsingQueryCache(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) 
    at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) 

그래서 문제점은 무엇입니까 : 스택 트레이스 별명? 그것은 NHibernate의 버그입니까? 다른 공급자를 사용해 보았습니다. 또한 나는이 같은 CacheableResultTransformer을 만들려고 :

CacheableResultTransformer.Create(Transformers.AliasToBean<SalesUnitDto>(), new[] { "Id", "Name" }, new[] { true, true }) 

반환하고 캐시 데이터 수 있지만, 단지 튜플 (객체 [])로. 나는 Dto를 돌려 줄 수 없었다. github

+0

어떻게'result'가 선언 되었습니까? –

+0

@Andrew Whitaker,'result'는'SalesUnitDto'입니다. –

+0

재생할 수 없습니다 - Cacheable()과 함께 작동합니다. NH v4.0.4.4000 –

답변

2

그것은 (N)의 절전 버그/제한 밝혀 : 여기

문제를 설명하는 동작 예이다. 캐싱이 활성화되면 원래 IResultTransformernullstring[] aliases 인수를 받기 시작합니다. 이는 AliasToBeanTransformer 구현에 필수적이며 따라서 예외가 발생합니다. 내가 전화했을 때 현재의 별칭을 저장하고에 전달 다음 사용자 정의 확장 방법과 변압기를 제안 할 수있는 해결 방법으로

하여 전달 된 인수가 nullAliasToBeanTransformer을 기본 :

public static class NHExtensions 
{ 
    public static IQueryOver<TRoot, TSubType> TransformUsingAliasToBean<TRoot, TSubType>(this IQueryOver<TRoot, TSubType> query, Type resultType) 
    { 
     ITupleSubsetResultTransformer resultTransformer = new AliasToBeanResultTransformer(resultType); 
     var criteria = query.UnderlyingCriteria as NHibernate.Impl.CriteriaImpl; 
     if (criteria != null) 
      resultTransformer = new CacheableAliasToBeenResultTransformer(resultTransformer, criteria.Projection.Aliases); 
     return query.TransformUsing(resultTransformer); 
    } 

    class CacheableAliasToBeenResultTransformer : ITupleSubsetResultTransformer 
    { 
     ITupleSubsetResultTransformer baseTransformer; 
     string[] aliases; 

     public CacheableAliasToBeenResultTransformer(ITupleSubsetResultTransformer baseTransformer, string[] aliases) 
     { 
      this.baseTransformer = baseTransformer; 
      this.aliases = aliases; 
     } 

     public bool[] IncludeInTransform(string[] aliases, int tupleLength) 
     { 
      return baseTransformer.IncludeInTransform(aliases ?? this.aliases, tupleLength); 
     } 

     public bool IsTransformedValueATupleElement(string[] aliases, int tupleLength) 
     { 
      return baseTransformer.IsTransformedValueATupleElement(aliases ?? this.aliases, tupleLength); 
     } 

     public IList TransformList(IList collection) 
     { 
      return baseTransformer.TransformList(collection); 
     } 

     public object TransformTuple(object[] tuple, string[] aliases) 
     { 
      return baseTransformer.TransformTuple(tuple, aliases ?? this.aliases); 
     } 
    } 
} 

당신이하고자 쿼리 be :

SalesUnitDto result = null; 
var list = _session.QueryOver<SalesUnit>() 
    .SelectList(l => l 
     .Select(x => x.Id).WithAlias(() => result.Id) 
     .Select(x => x.Name).WithAlias(() => result.Name)) 
    .TransformUsingAliasToBean(typeof(SalesUnitDto)) 
    .Cacheable() 
    .List<SalesUnitDto>(); 

이 시나리오에서 테스트되고 작동합니다. 물론 그것이 모든 QueryOver 유사 콘텐츠에 대해 작동한다고 보장 할 수는 없습니다.

1

이 NHibernate 버그는 v4.1.0.4000로 고정됩니다!

+0

을 참조하십시오. 많은 형제, 위대한 위대한! – vaqifrv

+0

선택한 방언에서 MaxAliastLength를 사용하여 서로를 소개하고 SQLite 드라이버로 내 통합 테스트를 수행하지 못했습니다. :( – dariol