当前位置:  开发笔记 > 编程语言 > 正文

以编程方式构建LINQ查询而没有局部变量欺骗我

如何解决《以编程方式构建LINQ查询而没有局部变量欺骗我》经验,为你挑选了3个好方法。

假设我的对象处于完美的工作状态(即TDD让我觉得它们有效).

我有一个我这样创建的列表(正确缩进除外):

var result = from v in vendors
             from p in v.Products
             orderby p.Name
             select p;

这有效 - 我从所有供应商处获得所有产品.

现在我有一个条件列表,由用户在运行时构建.让我们应用它们:

foreach (Attribute a in requiredAttributes)
{
    result = result.Where(p => p.Attributes.Contains(a));
}

这可能是原始的,但我认为它有用.但是,在完成此foreach循环之后,当您枚举"result"时,它将包含其Attributes属性(也是集合)中具有requiredAttributes集合的LAST属性的所有产品.

对我来说,这种气味就像"a"被覆盖在某个地方,每次旅行通过循环,只有最后一个适用.

如果没有以某种方式将扩展方法写入IEnumerable,称为ContainsAll(IEnumerable)或其他类似的东西,我怎么能实现我想要的,这基本上是一个逻辑AND,只给我那些具有所有必需属性的产品?



1> Jon Skeet..:

(为清晰起见而编辑.)

问题是foreach循环,以及每次捕获然后更改"a"变量的事实.这是一个有效的修改,通过为循环的每次迭代有效地引入一个"新"变量,并捕获该新变量.

foreach (Attribute a in requiredAttributes)
{
    Attribute copy = a;
    result = result.Where(p => p.Attributes.Contains(copy));
}

如果您可以使用它,Omer的解决方案更简洁,但如果您的真实代码实际上更复杂,这可能会有所帮助:)

编辑:关于这个闭包文章的问题还有更多- 向下滚动到"比较捕获策略:复杂性与功率".



2> Omer van Klo..:
var result = from v in vendors
             from p in v.Products
             where requiredAttributes.All(a => p.Attributes.Contains(a))
             orderby p.Name
             select p;

HTH.



3> Brian..:

我没有编码,但改变了

foreach (Attribute a in requiredAttributes){    
    result = result.Where(p => p.Attributes.Contains(a));
}

foreach (Attribute a in requiredAttributes){    
    Attribute b = a;
    result = result.Where(p => p.Attributes.Contains(b));
}

我想也应该修理它.

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有