2

私は実体を持っています私は2番目のレベルのキャッシュを接続するまで。したがって、Cacheable()行のコメントを外すと例外が発生します。NHibernateの第二レベルのキャッシュは

メッセージ:値はnullにはできません。パラメータ名: のStackTrace別名:

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の実装に不可欠です。

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); 
     } 
    } 
} 

とあなたが考えを照会:私が呼ばれたとき、現在のエイリアスを格納し、渡された引数がnullときに基礎となるAliasToBeanTransformerに渡し、次のカスタム拡張メソッドと変圧器を提案する可能性が回避策として

次のとおりです。

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

Unfortunatellyは、選択された方言でMaxAliastLengthを導入し、SQLiteドライバを使用したすべての統合テストに失敗します。 :( – dariol

関連する問題