这是一个适用于Linqpad的示例。问题是我需要它才能使用两个以上的单词,例如searchString =“床头板栏杆”。这是对索引的查询,而不是我已经完成的“匹配任何单词”,我需要它来“匹配所有单词”,在那里找到每个搜索单词的公共键值。
//Match ALL words for categories in index
string searchString = "headboard bed";
List<string> searchList = new List<string>(searchString.Split(' '));
string word1 = searchList[0];
string word2 = searchList[1];
var List1 = (from i in index
where i.word.ToUpper().Contains(word1)
select i.category.ID).ToList();
var List2 = (from i in index
where i.word.ToUpper().Contains(word2)
select i.category.ID).ToList();
//How can I make this work for more than two Lists?
var commonCats = List1.Intersect(List2).ToList();
var category = (from i in index
from s in commonCats
where commonCats.Contains(i.category.ID)
select new
{
MajorCategory = i.category.category1.description,
MinorCategory = i.category.description,
Taxable = i.category.taxable,
Life = i.category.life,
ID = i.category.ID
}).Distinct().OrderBy(i => i.MinorCategory);
category.Dump();
谢谢!
答案 0 :(得分:3)
交叉点的交叉点是可交换的和关联的。这意味着(A∩B∩C)=(A∩(B∩C))=((A∩B)∩C),重新排列列表的顺序不会改变结果。所以只需多次应用.Intersect()
:
var commonCats = List1.Intersect(List2).Intersect(List3).ToList();
所以,为了使你的代码更通用:
var searchList = searchString.Split(' ');
// Change "int" if this is not the type of i.category.ID in the query below.
IEnumerable<int> result = null;
foreach (string word in searchList)
{
var query = from i in index
where i.word.ToUpper().Contains(word1)
select i.category.ID;
result = (result == null) ? query : result.Intersect(query);
}
if (result == null)
throw new InvalidOperationException("No words supplied.");
var commonCats = result.ToList();
答案 1 :(得分:0)
要建立@ cdhowie的答案,为什么要使用Intersect
?我认为通过多个步骤构建查询可以提高效率。有点像...
if(string.IsNullOrWhitespace(search))
{
throw new InvalidOperationException("No word supplied.");
}
var query = index.AsQueryable();
var searchList = searchString.Split(' ');
foreach (string word in searchList)
{
query = query.Where(i => i.word.ToUpper().Contains(word));
}
var commonCats = query.Select(i => i.category.ID).ToList();