1

エンティティ コレクションに適用するさまざまな数の「フィルター」があり、これらのフィルターはリストに格納されます。現在、私は次のことを行っています。

    IQueryable<Items> items = SharedContext.Context.Items.GetAll();
    //This list is dynamic, but shown static here for simplicity
    IEnumerable<Items> filterList = new List<string>(){"new", "old", "current"};
    IEnumerable<Item> items_temp = new List<Item>();
    foreach (string type in filterList)
    {
        var temp = items.Where(i => i.Type.ToLower().Trim() == type.ToLower().Trim());
        items_temp = items_temp.Union(temp);
    }
    items = items_temp.AsQueryable();

残念ながら、これは大きなパフォーマンスの問題を引き起こします。私はそこに誰かがより良い解決策を持っていることを知っています.あなたはどう思いますか?

EDIT
上記のコードでアプリケーションを実行すると、実行に約30秒かかりますが、次の場合:

    items.Where(item => item.Type.ToLower().Trim() == "new" ||
                        item.Type.ToLower().Trim() == "old" ||
                        item.Type.ToLower().Trim() == "current");

私のアプリケーションは約 4 秒で実行されます。誰かがこのパフォーマンスに匹敵するソリューションを考え出すことができますか、または少なくとも結果がそれほど劇的に異なる理由について私に記入してもらえますか? 参考までに、複数のグリッドがネストされたグリッドにデータをバインドしています...小さな改善が大いに役立ちます。

4

2 に答える 2

4

あなたが望むのはこれのように聞こえます:

var items = SharedContext.Context.Items.GetAll();
IEnumerable<string> filterList = new List<string>(){"new", "old", "current"};
var filteredItems = items.Where(i => filterList.Contains(i.Type.ToLower()));

これに問題がある場合は、代わりに配列を使用してみてください。

string[] filterList = new string[] {"new", "old", "current"};
var filteredItems = items.Where(i => filterList.Contains(i.Type.ToLower()));

更新:フィルター式を動的に生成する別の戦略を次に示します。

var filterList = new[] { "new", "old", "current" };
var param = Expression.Parameter(typeof(Item));
var left = 
    Expression.Call(
        Expression.Call(
            Expression.PropertyOrField(param, "Type"),
            typeof(string).GetMethod("ToLower", Type.EmptyTypes)),
        typeof(string).GetMethod("Trim", Type.EmptyTypes));
var filterExpr = (Expression<Func<Item, bool>>)Expression.Lambda(
    filterList
        .Select(f => Expression.Equal(left, Expression.Constant(f)))
        .Aggregate((l, r) => Expression.OrElse(l, r)), 
    param);
var filteredItems = items.Where(filterExpr);
于 2013-07-25T17:21:14.840 に答える
2

結合を実行してアイテムをフィルタリングできます。

IEnumerable<Items> filterList = new List<string>(){"new", "old", "current"};          
IQueryable<Items> items = SharedContext.Context.Items.GetAll();

var filteredItems = from i items
                    join f in filterList 
                      on i.Type.ToLower().Trim() equals t.ToLower().Trim()
                    select i;
于 2013-07-25T17:35:49.607 に答える