3

sqlite DBでnhibernateを使用してc#で記述されたアプリがあります。ユニットテストには、xunitとインメモリsqliteデータベースを使用しています。

セッションが閉じられるとメモリ内DBが破棄されることを認識しているため、テストでは単一のセッションを使用し、テストの間は開いたままにします。私のテストのほとんどでは、これは正常に機能します。

ただし、いくつかのケースでは、との両方を使用するメソッドをテストする必要がISessionありIStatelessSessionます。少し調べた後、私はここで説明したアプローチに似たものに落ち着きました。したがって、は次のような'接続IStatelessSessionを使用して作成されます。ISession

statelessSession = factory.OpenStatelessSession(existingSession.Connection);

問題は、変更がDBに永続化されるとすぐに、これが何らかの競合を引き起こすように見えることです。でトランザクションを実行すると問題ありませんが、トランザクションを実行session.SaveOrUpdate(new Entity() {...})するstatelessSession.Get<Entity>(1)と、「コレクションはどのセッションにも関連付けられていません」というエラーメッセージが表示されて失敗します。

通常、このエラーはセッションが閉じていることを示しますが、この場合、両方のセッションはまだ開いていてアクティブです。

そうするとsession.Get<Entity>(1)、期待どおりにエンティティが返されます。当初、これはセッションとステートレスセッションが何らかの理由で同期していないことが原因である可能性があると考えたため、テストを置き換えsession.SaveOrUpdate..て再実行しました。statelessSession.Insert(new Entity() {...})不思議なことに、これは何の違いもありませんでした。通常のセッションは引き続き正常に機能し、statelessSessionは引き続き壊れています。

4

1 に答える 1

0

最後に、私はこのすべての解決策を見つけました:

最終的に、元のクエリ(複数の結果を返す上記の例よりも複雑なクエリ)に戻り、デバッグ中にさまざまなことを試しましたが、いずれも問題に光を当てることはありませんでした。次に、そのクエリの「where」部分を削除して、違いが生じるかどうかを確認することにしました。不思議なことに、そうしました。それでも失敗しましたが、今回は別の例外が発生しました:'クエリを実行できませんでした'、これにも内部例外がありました:'セッションへのスレッドセーフでないアクセスの可能性'。

テスト全体が単一のスレッドで実行され、デバッグ時にスレッドビューを確認してこれを確認しました。だから私は別のレンガの壁にぶつかると思った。しかし、グーグルした後、同じ問題と解決策を説明しているこのブログ投稿を見つけました。最新バージョンのnhibernateに更新するだけです。

3.1.0から3.3.1に更新しました(NUGetのおかげで、これは簡単でした)テストを再実行すると、機能しました。where句を元に戻し、テストに合格しました。

于 2013-01-03T11:03:40.800 に答える