2010-08-13 86 views
1

我似乎遇到了這個問題。我有一個帶有ID的任務表和一個標記表,它具有標記字段和任務表的外鍵約束。如何檢索用linq中所有提供的標籤標記的項目?

我希望能夠通過標籤執行AND搜索任務。例如,如果我搜索標籤爲「可移植性」和「測試」的任務,我不希望標記爲「可移植性」而不是「測試」的任務。

我試過的語法如下:

var tasks = (from t in _context.KnowledgeBaseTasks 
        where t.KnowledgeBaseTaskTags.Any(x => tags.Contains(x.tag)) 
        select KnowledgeBaseTaskViewModel.ConvertFromEntity(t) 
        ).ToList(); 

這當然不會OR搜索,而不是和搜索。我無法弄清楚如何實際切換這是一個AND搜索。

編輯 我還需要能夠搜索任務包含的X標籤中的2個。所以如果任務標記爲「bugfix」,「portability」,「testing」,並且我搜索「testing」和「portability」,那麼這個任務仍然會顯示出來。

回答

2

你想幹什麼this

的LinqToSql可能看起來像:

List<int> myTags = GetTagIds(); 
int tagCount = myTags.Count; 

IQueryable<int> subquery = 
    from tag in myDC.Tags 
    where myTags.Contains(tag.TagId) 
    group tag.TagId by tag.ContentId into g 
    where g.Distinct().Count() == tagCount 
    select g.Key; 

IQueryable<Content> query = myDC.Contents 
    .Where(c => subQuery.Contains(c.ContentId)); 

我沒有測試過這一點,含混位可能會關閉一些。檢查生成的sql是肯定的。

+0

這很好用(不得不添加ToList()到子查詢和Select()調用主查詢,但否則它工作。 – KallDrexx 2010-08-13 19:46:23

3

使用全部而不是任何;並且爲了只選擇知識庫任務,其中包含所有tags(但可能更多);反向表達:

var tasks = (from t in _context.KnowledgeBaseTasks 
       where tags.All(tag => t.KnowledgeBaseTaskTags.Contains(tag)) 
       select KnowledgeBaseTaskViewModel.ConvertFromEntity(t) 
       ).ToList(); 
+0

對不起,我應該更清楚。 All的問題是,如果我的任務也有一個「bugfix」標籤,只是搜索「可移植性」和「測試」標籤不會帶來它 – KallDrexx 2010-08-13 16:35:12

+0

@KallDrexx,請參閱編輯答案。 – driis 2010-08-13 16:40:25

+0

唯一的問題是你不能在KnowledgeBaseTags上包含(字符串),因爲它期望傳入一個KnowledgeBaseTag實體,而不是一個字符串。我嘗試使用'where tags.All(tag => t.KnowledgeBaseTaskTags.Any(entity => entity.tag == tag))',但是這會給出一個異常(本地序列不能用於查詢運算符的LINQ to SQL實現,除非包含運算符。) – KallDrexx 2010-08-13 18:45:32

相關問題