Linq集合在foreach的下一次迭代中重置
本文关键字:一次 迭代 集合 foreach Linq | 更新日期: 2023-09-27 18:06:34
我有下面的foreach
表达式,我在其中构建一个谓词,然后通过执行.Where()
来过滤集合。
但让我困惑的是,result.Count()
甚至在我在下一次迭代中执行.Where()
之前就给了我0
。
var result = SourceCollection;
foreach (var fieldName in FilterKeys)
{
if (!conditions.ContainsKey(fieldName)) continue;
if (!conditions[fieldName].IsNotNullOrEmpty()) continue;
var param = conditions[fieldName];
Func<BaseEntity, bool> predicate = (d) => fieldName != null && d.GetFieldValue(fieldName).ContainsIgnoreCase(param);
result = result.Where(predicate);
}
有人知道我可能忽略了导致这种情况的LINQ行为吗?
我想,你想要这个:
var result = SourceCollection;
foreach (var fieldName in FilterKeys)
{
if (!conditions.ContainsKey(fieldName)) continue;
if (!conditions[fieldName].IsNotNullOrEmpty()) continue;
var param = conditions[fieldName];
var f = fieldName
Func<BaseEntity, bool> predicate = (d) => f != null && d.GetFieldValue(f).ContainsIgnoreCase(param);
result = result.Where(predicate);
}
注意谓词中使用了f
。您不希望捕获foreach变量。在原始代码中,当第二次迭代开始时,param仍然是第一次迭代中捕获的值,但fieldName已更改。
我同意这个问题来自于没有捕获foreach
变量,但还有一个更深层次的问题,那就是LINQ与命令控制流结构的结合,即混合LINQ&CCD_ 8。
试试这个:
var predicates =
from fieldName in FilterKeys
where conditions.ContainsKey(fieldName)
let param = conditions[fieldName]
where param.IsNotNullOrEmpty()
select (Func<BaseEntity, bool>)
(d => fieldName != null
&& d.GetFieldValue(fieldName).ContainsIgnoreCase(param));
var result = predicates.Aggregate(
SourceCollection as IEnumerable<BaseEntity>,
(xs, p) => xs.Where(p));
不需要foreach
循环,代码完全停留在LINQ中。朋友不应该让朋友把命令性和功能性混为一谈…:-(