2011-06-28 9 views
0

私は通常、自分のアプリケーションで "ページ - >サービス - >リポジトリ"パターンを使用して、すべてのデータベース呼び出しを "リポジトリ"クラスに入れます。NHibernate collection Count()ジレンマ

サービスロジックで収集項目数をテストする場合があります。

例:

EventService eventService=container.Resolve<EventService>(); 
IEnumerable<Event> events=eventService.GetAll(); 
if(events.Count()>0) 
{ 
    ...do something... 
} 

これは私のリポジトリクラスのうちDBアクセスを自動的にSQL文を生成しますNHibernateはを使用します。

これを避けることはできますか?ベストプラクティスはありますか?

+0

データベースにアクセスせずにデータベースの永続オブジェクトをカウントしますか?私はあなたの質問を理解するのが少し難しいです。 –

答えて

4

私は、次のような理由から、リポジトリにIQueryable<T>の公開を回避しよう:サポートされている方法の多くはか

  • 、生成されるクエリの種類は必ずしも明確ではありません。
  • アドホッククエリをサポートすることにより、特定のユースケースに対して適切なインデックスを設計する重要性が損なわれます。
  • 予想される種類のクエリの指定が失われます。

代わりに、リポジトリに必要なものに変換される単純なクエリオブジェクトを使用することを選択します。

IList<Event> GetAll(int startIndex, int count); 

これはまた、ページネーションの重要性を強調:

は、特にこのような場合のために、私はイベントのページ番号付きリストを返すリポジトリ上のメソッドを持っているでしょう。あなたはまた、同様に合計数を含めることができるのIList用ラッピングオブジェクトを作成することもできます

this.Session.Linq<Event>().Skip(startIndex).Take(count).ToList(); 

:リポジトリではこのような何かをしたいと思います。

1

サービス層をテストする場合は、リポジトリを嘲笑する必要があります。オブジェクトの静的リストをIQueryableとして公開して、モックリポジトリを作成できます。

このようにCount()を呼び出すと、確実にアサートできる静的リストのカウントが返されます。

更新

私の間違いは、私がテストコレクションのアイテムにしました にあなたは、このロジックをテストしたかった私のサービスロジック

をカウントし、このラインから

を仮定あなたのサービス。

上記のコードは、IQueryableを返すようです。したがって、Count()またはToList()(本質的にIQueryableを列挙しているもの)を呼び出すとすぐに、データベースにヒットします。

のでIList<T>を返すか、以下のようにコードを変更するために、あなたのサービスを変更、次のいずれか

EventService eventService=container.Resolve<EventService>(); 
IEnumerable<Event> events = eventService.GetAll().ToList(); 
if(events.Count()>0) {  ...do something... } 

あなたが作業しているとして、あなたがCount()を呼び出すときあなたはToList()を呼び出すときにデータベースをヒットしませんが、 - メモリコレクション。

+0

いいえ!これはユニットテストコードではありません。これはServiceクラスの例です。 – danyolgiax

+0

私はあなたの質問を誤解し、私の答えを更新しました。 –