LINQ where子句 - 比较字符串集合

时间:2013-07-25 17:18:50

标签: c# linq linq-to-sql

我有一个可变数量的“过滤器”要应用于实体集合,这些过滤器存储在List中。现在,我正在做以下事情:

    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();

不幸的是,这会导致巨大的性能问题。我知道有人有更好的解决方案......你们有什么想法?

修改
使用上面的代码运行我的应用程序大约需要30秒才能执行,但是如果执行以下操作:

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

我的应用程序在大约4秒内执行。任何人都可以想到一个能够与这种表现相匹配的解决方案,或者至少让我了解为什么结果如此截然不同?仅供参考,我将我的数据绑定到一个嵌入了多个网格的网格中...一个小的改进可以有很长的路要走。

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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;