我有一个可变数量的“过滤器”要应用于实体集合,这些过滤器存储在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秒内执行。任何人都可以想到一个能够与这种表现相匹配的解决方案,或者至少让我了解为什么结果如此截然不同?仅供参考,我将我的数据绑定到一个嵌入了多个网格的网格中...一个小的改进可以有很长的路要走。
答案 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;