3

NHibernate の二次キャッシュに問題があります。クエリを使用する場合:

        var items1 = Session.Query<Row>()
            .Cacheable();
            .Fetch(x => x.Field)
            .OrderBy(x => x.Field.Value)
            .ToList();

すべて問題ありません。クエリはキャッシュされています。しかし、Dynamic Linq ( a link )を使用したい場合:

       var items2 = Session.Query<Row>()
            .Cacheable();
            .Fetch(x => x.Field)
            .OrderBy("Field.Value")
            .ToList();

クエリはキャッシュされません。興味深いことに、コード行を削除すると:

            .Fetch(x => x.Field)

キャッシングは再び機能します。したがって、問題は Fetch と動的 linq OrderBy メソッドを一緒に使用することです。

編集:

NH コード (QueryKey クラス) をデバッグしようとすると、デバッガーは、これら 2 つのクエリに同じ ResultTransformer (さらに深いところ: listTransformation プライベート インスタンス) がないことを通知します。

何か案は?

クリス

4

1 に答える 1

2

わかりました、私は理由が何であるかを知っています。

動的Linqは、Linq式でパラメーター名を使用しません。たとえば、ラムダステートマントを使用して並べ替える場合は、次のように記述します。

query.OrderBy(item => item.Name)

上にitemラムダパラメーター名が表示されています。

Dynamic linqを使用する場合:

query.OrderBy("Name")

結果のQueryableでは、OrderBy mehodのラムダパラメーターに名前がありません(item上記のように)。結果は次のように説明できます。

query.OrderBy( => .Name)

そして今、NHibernateがそのQueryable式をデコードしていて、名前のない式パラメーターが見つかった場合、NHはGUIDクラスを使用してランダムな名前を付けます。したがって、動的linqを使用するすべての順序付けにより、ラムダパラメーターが一定でないクエリ可能な式が生成されます。これが、NHibernateが次のように考える理由です。同じではquery.OrderBy("Name")ありquery.OrderBy("Name")ません。毎回ゼロから生成される別のlamdaパラメーターがあります。

解決

修正したい場合は、DynamicLinqライブラリを変更する必要があります。

  1. メソッドExpressionParser.ProcessParameters変更行:

    if (parameters.Length == 1 && String.IsNullOrEmpty(parameters[0].Name))
    

    に:

    if (parameters.Length == 1 && (parameters[0].Name == "it" || String.IsNullOrEmpty(parameters[0].Name)))
    
  2. メソッドDynamicQueryable.OrderBy変更行:

    Expression.Parameter(source.ElementType, "")
    

    に:

    Expression.Parameter(source.ElementType, "it")
    

今、query.OrderBy("Name")を生成しquery.OrderBy(it => it.Name)ます。

乾杯!

于 2012-08-14T14:00:18.607 に答える