2011-07-10 7 views
0

私のアプリケーションをDAL、BL、UIに分けました。エンティティフレームワークを使用しているC#のデータベースへのクエリでメソッドを使用する代わりに

私は、SQLデータベースにアクセスするために、エンティティフレームワークのコードを最初にスローするリポジトリを使用しました。

public class Person{ 
    ... 
}  
public class PersonRepository{ 

    Create(...){...} 
    Update(...){...} 
    Delete(...){...} 
    GetById(...){...} 
    Query(...){...} 

    ... 

今の事は、私は住所

public GetPersonsNear(string Address){ 
... 
} 
private bool AddressesAreClose(string address1, string address2) 
{ 
... 
} 

の近くに残されているすべての人を取得する方法に取り組んでいるBLである事は、LINQ does'nt私のメソッドを使用してみましょうです(リポジトリの「クエリ」方法で渡されたクエリで)

... 
PersonRepository personRepository = new PersonRepository(); 
var person = repository.Query(p => AddressAreClose(adress,p.Adress); 
... 

そのためには、私がテストをするために、単純なforeachループを使用してのみ関連を保ち、リスト内の表のすべての要素を取得するために必要もの今の

... 
PersonRepository personRepository = new PersonRepository(); 
var persons = personRepository.GetAll; 
foreach(person in persons) 
{ 
    if(AdressAreClose(adress,person.adress)) 
    ... 
    } 

私はそれをテストするための唯一のいくつかの要素を持つデータベースを埋め、私はそれはそれはi「は、すべてのテストで、後に特別に含まれていますはるかに多い数で非常にうまく機能わかりません追加する予定です

これはもっと巧妙な方法ですか?私は何かを開いている

答えて

1

まず、Personに制約されていても、まずジェネリックスをリポジトリで使用する必要があります。このようにして、LINQクエリをクリーンアップして再利用を容易にするために、クエリからパイプ/フィルタを構築できます。

もちろん、Queryメソッドの完全な署名/実装を見ることなく、わかりにくいです。しかしどちらの方法でも、IEnumerable<Person>またはIQueryable<Person>を返す必要があります。

だから、あなたはこのように、パイプ/フィルタにAddressesAreCloseを回すことができる:あなたのデータのサイズに応じて

var person = repository 
    .Query() // Should be IQueryable<Person> 
    .WhereAddressAreClose(adress); 
    .ToList(); 

public static bool WhereAddressesAreClose(this IQueryable<Person> source, string address) 
{ 
    return source.Where(/* your conditions */); 
} 

次に、あなたがあなたのLINQクエリでそれを使用することができます実装キャッシュの有無にかかわらず、foreachループを使用してクエリを実行するのではなく、サーバー(データベース)の結果を制限する必要があります。

パフォーマンスがあまり良くない場合は、インデックスの追加、コンパイルされたクエリの使用、またはストアドプロシージャへの移動を検討してください。

関連する問題