2011-04-03 9 views
1

Webアプリケーションのエンティティフレームワークの使用を開始し、ユーザがリストを動的にフィルタリングできるようにするための最良の方法を知りたいと考えています。 ieユーザーが姓、市などでフィルタリングできる人のリストがある場合エンティティフレームワーク4フィルタを使用した一般的なリストメソッド

問題は私がコードで最初にEF 4を使用していて、Linqクエリしかし、ユーザーが選択したフィルタオプションに基づいて、フィルタのwhere句を動的に構築する方法はわかりません。つまり、SQLで構築することができます

select * from people, address where lastname = 'jones' and address.city = 'sydney' 

linqを使ってこのリストを動的に構築する方法はありますか?

EDIT
は、私が試してみるつもりだソリューションは、このImplementing Dynamic Searching Using LINQのようになります。できる限りジェネリックであることを好むので、できる限り。

答えて

3

の方法は、検索条件のいくつかのタイプを定義する例です:

public class PeopleSearchCriteria 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string City { get; set; } 
} 

IQueryable<Person>のカスタム拡張メソッドを定義します。

public static IQueryable<Person> FilterBySearchCriteria(this IQueryable<Person> query, 
    PeoplseSearchCritera criteria) 
{ 
    if (!String.IsNullOrEmpty(criteria.FirstName)) 
    { 
     string firstName = criteria.FirstName; 
     query = query.Where(p => p.FirstName == firstName); 
    } 

    // do similar code for other criterias 

    return query; 
} 

今、あなただけ作成する必要がありますモデルバインダー(または、可能であればデフォルトのものを使用)を使用して、セクターオプションをPeopleSearchCriteriaインスタンスに入力し、単純に実行します。

var data = context.People.FilterBySearchCriteria(searchCriteria).ToList(); 

動的なアプローチが本当に必要な場合は、式ツリーを手動で作成するか、Dynamic Linq(コンパイル時のチェックを失う)をチェックすることができます。

+0

ありがとうございます、あなたの提案と動的なlinqの間にパフォーマンスの違いはありますか? – eaglestorm

+0

私はこの違いとダイナミックなlinqの間にどれほど大きな違いがあるのか​​分かりません。私が知っているように、動的linqは 'Reflection.Emit'を内部的に使っていますが、その使用法に影響はありませんでした。 –

0

例:
これは、フィルタリングされた人のコレクションを取得します。

var people = EfDBContextEntities.people; // depends on your context and naming 

var filteredPeople = 
from p in people 
where p.lastname == "jones" 
select p; 

使用すると、1つのコレクションで両方のエンティティを返すようにしたい場合は、あなたが何か行うことができますより:

var myCollection = 
from p in people 
from a in address 
where p.lastname == "jones" 
where a.city == "sydney" 
select new {person = p, address = a}; 

をあなたがオブジェクトのコレクションを取得し、あなたのようにそれらにアクセスすることができるようになります。

foreach (var item in myCollection) 
{ 
    var personName = item.person.lastname; 
    var cityAddress = item.address.city; 
} 
+0

ユーザー入力に基づいてクエリのwhereセクションを構築し、ハードコーディングしないようにしたいという点が欠落していると思います。 – eaglestorm

+0

どの列を照会するか、またはどの値をフィルターに掛けるかを選択しますか? – Damb

0

私は物事のような種類のリポジトリのパターンを使用することを示唆しています

http://msdn.microsoft.com/en-us/library/ff649690.aspx

ここは例です。

public class PeopleRepository { 

    HumanEntities _entities = new HumanEntities(); 

    public IQueryable<people> GetAll() { 

    IQueryable<people> query = _entities.Customers; 

    retun query; 

    } 

    public IQueryable<people> GetAll(string _lastname, string _city) { 

    //I am thinking that people and address tables are related to each other 
    //as one to many or many to many. So the example should look like below; 
    var query = GetAll().Where(x => x.lastname = _lastname && x.address.city = _city); 

    retun query; 

    } 

    public void Save() { 

    _entities.SaveChages() 

    } 
} 

以降、クラス外で簡単に使用できます。以下のように。

PeopleRepository _repo = new PeopleRepository(); 

DataList1.DataSource = _repo.GetAll("ugurlu", "LA"); 

あなたは、ユーザー入力としてパラメータが必要だと述べました。私はあなたのエンティティモデル(asp.net Webフォーム、winフォームまたはasp.net MVC)を使用するか分からないが、ここにその例がある。これを行うには

PeopleRepository _repo = new PeopleRepository(); 

DataList1.DataSource = _repo.GetAll(LastnameTextBox.Text, CityTextBox.Text);