1

经过数小时的尝试和搜索,我想现在是时候与您分享我的问题了。

问题定义:我有一个KeyValuePairs 字典(名为filterPool),其中包括一个整数(PropertyID)和一个字符串(McValue)。我想要做的是根据这些 KeyValuePairs 过滤产品并将它们作为DataTable/List返回。您可以将其视为将动态“Where ... And ..”子句构建为 SQL。

这是我正在使用的代码:

            foreach (KeyValuePair<int, string> filter in filterPool)
            {
                products = products.Where(i => i.PROPERTYID == filter.Key && i.MCVALUE.Equals(filter.Value));
            }
            return products.ToDataTable();                  

问题是上面的 foreach 循环似乎只工作一次,对于字典中可用的最新 KeyValuePair。

据我在 Stackoverflow 上找到的,最接近我的问题的解决方案是:这个,也使用值字典进行过滤

必须有一种方法可以实现使用 Dictionary 和 LINQ 进行过滤的目标;或者有一件我想念/忽略的大事。

希望给出的问题对所有人来说都足够清楚,谢谢^^

4

3 回答 3

2

这是一个关闭问题。您可以通过临时解决它:

        foreach (KeyValuePair<int, string> filterTmp in filterPool)
        {
            var filter = filterTmp; // Make a temporary
            products = products.Where(i => i.PROPERTYID == filter.Key && i.MCVALUE.Equals(filter.Value));
        }
        return products.ToDataTable();   

有关正在发生的事情的详细信息,请参阅 Eric Lippert 的帖子关闭被认为有害的循环变量

另请注意,对于 C# 5,此行为已更改。在 C# 5/VS2012 中,此代码将按预期工作。

于 2012-08-09T19:10:58.797 回答
1

您在 foreach 的每次迭代中都覆盖了您的产品集合。我不确定你的集合中的数据类型是什么,但你会想在你的 foreach 中做这样的事情:

products.AddRange(products.Where(i => i.PROPERTYID == filter.Key && i.MCVALUE.Equals(filter.Value)));

我不确定这是否有意义,但您似乎正在尝试创建一个包含与您的 filterPool 匹配的产品的集合。

于 2012-08-09T19:11:57.967 回答
0

我认为用聚合更好地解决它:

return filter
    .Aggregate(products, (acc, filter) => acc.Where(i => i.PROPERTYID == filter.Key && i.MCVALUE.Equals(filter.Value)));
    .ToDataTable();
于 2012-08-09T19:26:50.637 回答