0

JobGroupの2 つの関連エンティティがあり、多対多の関係があります。

特定のジョブとそれに関連付けられているグループを取得するための簡単なクエリを実行しています ( GroupRecipientsプロパティを介して):

var job = jobsRepo.Get()
                .Where(j => j.Id == jobKey.Id)
                .FirstOrDefault();

var countA = job.GroupRecipients.Count;

その結果はcountA==2で、データベースの状態に対応します。

最初の奇妙な点は、FetchMany を追加したときに発生します。

var job = jobsRepo.Get()
                .FetchMany(x => x.GroupRecipients)
                .Where(j => j.Id == jobKey.Id)
                .FirstOrDefault();

var countB = job.GroupRecipients.Count;

この結果はcountB==1になります。job.GroupRecipients コレクションには 1 つのアイテムしか表示されません。これは、データベース内の状態と矛盾しています。

しかし、それはさらに興味深いものになります。以下を連続して実行すると:

var job = jobsRepo.Get()
                .Where(j => j.Id == jobKey.Id)
                .FirstOrDefault();

var countA = job.GroupRecipients.Count;

var jobB = jobsRepo.Get()
                .FetchMany(x => x.GroupRecipients)
                .Where(j => j.Id == jobKey.Id)
                .FirstOrDefault();

var countB = jobB.GroupRecipients.Count;

次に、期待される結果であるcountB==2を取得します。countA を含む行を再度削除すると、countB==1が発生します。

詳細情報:ステートレス セッションのトランザクションでクエリを実行します。NHibernate のバージョンは3.3.1です

したがって、この 2 つの問題は次のように要約できます。

  1. FetchMany は部分的な結果を返します
  2. あるクエリが予期しない方法で別のクエリに依存しています。

この動作の説明は大歓迎です。

4

1 に答える 1

2

これは、LINQ プロバイダーが処理する方法のバグまたは不一致のようですFirstOrDefault。私の場合、クエリにブランケットを追加しているように見えLIMIT 1ますが、これは明らかに熱心な読み込みでは機能しません (結果としてOUTER JOIN.

途中で列挙可能なものに明示的に変換することで解決しました:

var job = jobsRepo.Get()
                  .FetchMany(x => x.GroupRecipients)
                  .AsEnumerable()
                  .FirstOrDefault(j => j.Id == jobKey.Id);

これはちょっとしたハックですが、問題を解決します。

おそらく、最初のエンティティがキャッシュに読み込まれるため、2 番目の例が機能するため、nHibernate はデータベースにアクセスする必要性を感じません (そして、LINQ プロバイダーで障害のあるロジックに遭遇します)。

于 2013-05-20T11:41:36.957 に答える