在没有局部变量的情况下以编程方式构建LINQ查询 [英] Building a LINQ query programmatically without local variables tricking me

查看:72
本文介绍了在没有局部变量的情况下以编程方式构建LINQ查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的对象处于完美的工作状态(即TDD使我认为它们可以工作).

Assume my objects are in perfect working order (i.e. TDD makes me think they work).

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

I have a list that I create like this (except indented properly):

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

这行得通-我从所有供应商处获得了所有产品.

This works - I get all products from all vendors.

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

Now I have a list of conditions, built up at runtime by the user. Let's apply them:

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

这可能是原始的,但我认为它可以工作.但是,在此foreach循环完成后,当您枚举结果"时,它将包含所有在Attributes属性(也是一个集合)中具有requiredAttributes集合的LAST Attribute的所有产品.

This may be primitive, but I thought it'd work. However, after this foreach loop is finished, when you enumerate "result" it will contain all products that has the LAST Attribute of the requiredAttributes collection in it's Attributes property (also a collection).

对我来说,这听起来像是"a"被遍历循环的某处覆盖,而只有最后一个适用.

To me, this smells like "a" is overwritten somewhere with each trip trough the loop, and only the last one applies.

某种程度上以某种方式向IEnumerable写了一个名为ContainsAll(IEnumerable)的扩展方法或达到这种效果的东西,我怎么能实现我想要的,这基本上是一个逻辑与,仅给我那些具有所有必需属性的产品?

Short of somehow writing an extension method to IEnumerable called ContainsAll(IEnumerable) or something to that effect, how can I achieve what I want, which is basically a logical AND, giving me only those products that has ALL the required attributes?

推荐答案

(为清楚起见进行了编辑.)

(Edited for clarity.)

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

The problem is the foreach loop, and the fact that the "a" variable is being captured and then changed each time. Here's a modification which will work, by effectively introducing a "new" variable for each iteration of the loop, and capturing that new variable.

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

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

Omer's solution is a cleaner one if you can use it, but this may help if your real code is actually more complicated :)

此关闭文章中,有关此问题的更多信息-向下滚动至比较捕获策略:复杂性与功耗".

There's more about the issue in this closures article - scroll down to "Comparing capture strategies: complexity vs power".

这篇关于在没有局部变量的情况下以编程方式构建LINQ查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆