6

私はASP.NET MVC 3を使用しています。私は、次の順序で私のビューのデータを取得:私のリポジトリにデータのフィルタリングはコントローラ、サービス、またはレポジトリのレイヤで行われますか?

Controller -> Service Layer -> Repository 

は私がカテゴリーのように、特定のオブジェクトのすべてのレコードを戻しますGETALLの方法があります。今

public IEnumerable<Category> GetAll() 
{ 
    return categoryRepository.GetAll(); 
} 

:私はのようなものを持つことになり、サービス層で

IEnumerable<Category> categories = categoryService.GetAll(); 

:私はすべてのカテゴリのリストが必要な場合

それでは、私のコントローラで私のようなものを持っているでしょうこれは私が実際にデータをフィルタリングし始めるところを知る必要があるのですか?これらの3つのレイヤーのいずれかでどこでも実行できますか、またはリポジトリレイヤー内にあるだけですか?私はすべての親カテゴリが必要だと言うことができます。コントローラ、サービスレイヤ、またはリポジトリレイヤに.GetAll.Where(x => x.ParentCategoryId == null);がありますか?

私は私のコントローラでこのようにそれを持っていますか:

IEnumerable<Category> categories = categoryService.GetParentCategories(); 

そして、私のサービス層では、私が持つことができます。

public IEnumerable<Category> GetParentCategories() 
{ 
    return categoryRepository.GetAll.Where(x => x.ParentCategoryId == null); 
} 

それとも私のサービス層はこのように見ているん:

public IEnumerable<Category> GetParentCategories() 
{ 
    return categoryRepository.GetParentCategories(); 
} 

次に、このような私のリポジトリのレイヤー:

public IEnumerable<Category> GetParentCategories() 
{ 
    return GetAll() 
      .Where(x => x.ParentCategoryId == null); 
} 

私はこの混乱を明確にするのに役立つ人がいますか?さまざまなシナリオがあります。私はアクティブなステータスを持つすべてのカテゴリを返すかもしれません。私は非アクティブ状態のカテゴリを戻すかもしれません。それから私はそれぞれのためのメソッドが必要ですか?

答えて

4

データソースから最も近いところでフィルタリングする必要があります。そうしないと、フィルタリングオプションのために破棄されるだけの上位レイヤのレコードが取得されます。これはうまく拡張されないため、必要なすべてのレイヤーでフィルタリング機能を公開する必要がありますが、実際のフィルタリングは可能な限り最下位層で実行されます。通常、データベースレベルで実行されます。

GetAllを使用して投稿した例では、すべてのレコードのIEnumerableが返され、その後は基本的にテーブル全体をメモリにロードしてから、フィルタリング。

EFを使用しているので、IQueryableの遅延実行プロパティを利用できます。チェック:

.NET Entity Framework - IEnumerable VS. IQueryable

Should a Repository return IEnumerable , IQueryable or List?


更新:をあなたもチェックする必要がありますあなたのコメントにフォローアップ:

LINQ to entities vs LINQ to objects - Are they the same?

+0

GetAllは単なるサンプルメソッドですが、主な焦点はフィルタリング部分です。次に、リポジトリにメソッドを1つずつ作成しますか?しかし、Where節を持つSQL Selectのような.Where(...)は動作しませんか? –

+0

エンティティにLINQを使用している場合にのみ、そのために 'IQueryable'が必要です。 –

+0

はい。私はメソッドを取得しているので、リポジトリはそれがスローされるすべての条件を処理できます。 GetALlUsers()メソッドを使用すると、私は人々に火をつけます。地獄のように非効率的です。名前をつけて100.9000人のユーザーを引っ張る - いいえ。 – TomTom

2

をあなたはいつものように少しを取得しようとする必要がありますできるだけデータベースから削除してください。したがって、すべてのフィルタリングはリポジトリクラスで行う必要があります。

多くの記事では、一般的なリポジトリを作成して使用することを提案しています。しかし、あなたのアプリケーションが成長しても、imhoはうまく動作しません。私はあなたのような適切な検索方法で、適切なリポジトリクラスを作成することをお勧めします。

emailRepository.GetForUser("Ada"); 
userRepository.GetNewUsers(); 

まず第一に、あなたは新しいユーザーを特定する方法のような実装の詳細を隠します。また、一般的なクエリを使用するよりも、コードの理解と拡張が容易になります。

また、いくつかのフィルタリングオプションを追加することができます。

emailRepository.GetForUser("Ada", Filtering.New().Paged(1, 20).SortedBy("FirstName")); 

@JoãoAngeloと違って、私はあなたがあなたのリポジトリのIQueryable外を使用することをお勧めしません。これにより、データベースの実行をリポジトリクラスの外に移動します。つまり、エラーはリポジトリで処理できません。

関連する問題