我有一系列关键字:splitKeywords = {“KeywordA”,“KeywordB”,“KeywordC”}
实体KeywordSearch:
public class KeywordSearch
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
// Navigation properties
public Keyword Keyword { get; set; }
}
关键字的位置是:
public class Keyword
{
// Primary properties
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<KeywordSearch> KeywordSearches { get; set; }
}
如何基于所有macthing KeywordSearch构建KeywordIds数组?
我有这个非常丑陋的代码:
var keywordSearchQuery = _keywordSearchRepository.Query;
List<int> keywordIds = new List<int>();
foreach (var keyword in splitKeywords)
{
var keywordsFound = keywordSearchQuery.Where(kws => kws.Name == keyword).Select(kws => kws.Keyword.Id);
if (keywordsFound.Count() == 0)
{
keywordIds.Clear();
return null;
}
else
{
keywordIds.AddRange(keywordsFound);
}
}
我有这个,但它会返回任何匹配的关键字:
keywordIds = keywordSearchQuery.Where(ks => splitKeywords.Contains(ks.Name)).Select(ks => ks.Keyword.Id);
编辑:
示例:
KeywordSearch = { 1, "KEYWORDA", { 1, "KeywordA" }},
{ 2, "KEYWORDB", { 2, "KeywordB" }},
{ 3, "KEYWORDC", {3, "KeywordC" }}
If I search for "KEYWORDA", I get KeywordId = 1
If I search for "KEYWORDA KEYWORDB", I get KeywordId = 1,2
If I search for "KEYWORDA KEYWORDX", I get NULL
答案 0 :(得分:1)
您在概念上正在做的是加入这两个系列。
任何时候你发现一个集合中的所有项目都是foreach
循环的当前项目,你应该查看一个联接,因为这可能就是你正在做的事情。
加入不仅更清洁,而且效率更高:
var query = from keywordSearch _keywordSearchRepository.Query
join keyword in splitKeywords
on keywordSearch.Name equals keyword
select keywordSearch.Keyword.Id;
return query; //add a ToList here if it's important to materialize the query now
答案 1 :(得分:0)
这是一种方法;它适用于LINQ to Objects,我不确定在通过EF查询时它是如何工作的。
var keywordIds = from keyword in _keywordRepository
where splitKeywords.Intersect(keyword.KeywordSearches.Select(kws => kws.Name))
.Count() == splitKeywords.Count
select keyword.Id;
请注意,此查询基于_keywordRepository
而非_keywordSearchRepository
。我认为以这种方式构造查询更有意义。