5

我想使用 myFilters 从 myCollection 中选择元素进行过滤:

var myFilters = new List<string> {"111", "222"};
var myCollection = new List<SomeClass> {
                      new SomeClass ("111"), 
                      new SomeClass ("999")
                   };

from filter in myFilters
from item in myCollection
where item.Name == filter
select item

将返回“111”项目。

但是,如果 myFilters 为空,我想从 myCollection 返回所有项目。

var myFilters = new List<string> ();
var myCollection = new List<SomeClass> {
                          new SomeClass ("111"), 
                          new SomeClass ("999")
                    };

// Here's where I'm lost...
from filter in myFilters
from item in myCollection
where item.Name == filter
select item

将返回所有项目(“111”和“999”)。

4

5 回答 5

8

如果这些集合非常大,那么我建议使用连接。它看起来像这样:

var result = 
    myFilters.Any() ?
        from item in myCollection
        join filter in myFilters
        on item.Name equals filter into gj
        where gj.Any()
        select item
    : myCollection;

使用连接的机会很容易被忽视。当列表远程很大时,这种连接方法将优于包含方法。如果它们很小并且性能可以接受,那么使用看起来最清晰的那个。

于 2012-09-13T01:17:17.130 回答
5
var result = myCollection
                   .Where(i => (!myFilters.Any() || myFilters.Contains(i.Name)));
于 2012-09-13T04:45:40.903 回答
2

您能做的最好的事情就是将过滤器投影到 SomeClass 中。就像是:

var results = myCollection.Any() ?
    myCollection.Where(item => myFilters.Contains(item.Name)) :
    myFilters.Select(f => new SomeClass (f));
于 2012-09-13T00:46:12.777 回答
0

这个怎么样?

var myFilters = new List<string> ();
var myCollection = new List<SomeClass> {new SomeClass ("111"), new SomeClass ("999")};

// Here's where I'm lost...
from filter in myFilters
from item in myCollection
where item.Name == filter || !myFilters.Any()
select item

从两个集合中进行选择会根据您的 where 子句执行连接。上面的加入条件说加入 item.Name 等于过滤器,如果没有可用的过滤器,则选择它。

于 2012-09-13T01:24:53.477 回答
0

尝试这个:

var result = myCollection.Where(s => !myFilters.Any() ||
                                     myFilters.Contains(s.Name));
//EDIT: commented these lines..based on comment by @Servy
//var result = myCollection.Where(s => myFilters.Count == 0 ||
//                                     myFilters.Contains(s.Name));

也许最好只计算一次过滤器集合:

bool isFilterEmpty = !myFilters.Any(); 
//bool isFilterEmpty = myFilters.Count == 0;    //...or like this
var result = myCollection.Where(s => isFilterEmpty || 
                                     myFilters.Contains(s.Name));

编辑

我什至会说@itsme86 的答案是正确的,但是,我猜,他混淆了你的收藏。所以他的答案应该是这样的:

var results = myFilters.Any()
                 ? myCollection.Where(item => myFilters.Contains(item.Name))
                 : myCollection;
于 2012-09-13T00:58:20.910 回答