2012-02-13 8 views
1

私のMVCサイトでは、データアクセスにEF 4.1を使用しています。今は製品検索機能を開発しています。フィルタ製品を取得するためのメソッドシグネチャは次のとおりです。Entity Framework効率的なクエリフィルタ

PagedList<Dress> GetDressesPage<TKey>(int page, int dressesPerPage, Func<Dress, bool> selection, Func<Dress, TKey> order, SortDirection direction); 

と私は製品を入手する方法は次のとおりです。

dresses = _context.Dresses.Where(selection).OrderBy(order).Skip(page * dressesPerPage).Take(dressesPerPage).ToList(); 

問題は機能選択です。私は別の条件を追加することでそれを構築できるようにしたいと思います。今は、パラメータの組み合わせごとにいくつかのif節を使って構築していますが、それは複雑すぎます。

フィルタをパラメータとして渡す簡単な方法をご存知ですか?

答えて

4

Predicate Builderを使用してください。 Func<Dress, bool>Expression<Func<Dress, bool>>に置き換えます。そうしないと、クエリはLINQ-to-Objectsに変わります。

var predicate = PredicateBuilder.True<Dress>(); 
    if (!string.IsNullOrEmpty(name)) 
    { 
     predicate = predicate.And(d => d.Name.Contains(name)); 
    } 

    dresses = _context.Dresses.Where(predicate).OrderBy(order) 
     .Skip(page * dressesPerPage).Take(dressesPerPage).ToList(); 
0

"LinqKit"の完璧なライブラリです。

使用例:

public static IEnumerable<DressItem> QueryDresses(FashionEntities ctx, Expression<Func<dresses, bool>> predicate) 
    { 
     var query = (from dress in ctx.dresses 
         .AsExpandable() 
         .Where(predicate)      
        select new DressItem { 
         id = dress.Id, 
         name = dress.Name, 
         price = dress.Price 
        }; 
     return query; 
    } 

あなたが見ることができるように、この方法は、次のように呼び出し元のメソッドに構築することができます述語を受け付けます

Expression<Func<dresses, bool>> predicate = d => d.Price > 1000; 

    if (lalalala == llalala) { 
     predicate = d => d.Price > 2000; 
    } 

    var result = new List<DressItem>(); 
    using (var ctx = new FashionEntities()) 
    { 
     var dresses = QueryDresses(ctx, predicate.Expand()); 
     result = dresses.ToList(); 
    } 
関連する問題