2013-11-01 46 views
1

场景:吨-SQL子查询组

  • 模块1具有标签AB
  • 模块2具有标签AB
  • 模块3具有标签A
  • 模块4具有标签B
  • 模块5具有标签ABC

在表:

ModuleId TagId 
1   A 
1   B 
2   A 
2   B 
3   A 
4   B 
5   A 
5   B 
5   C 

条件:

  • 我有标签识别前的列表:列出<>标记列表= {A,B}
  • 我想所有这些TagIds下相同的moduleId下降,比TagIds列表其他(即tagList)。从而导致它应该返回标签识别C.

TSQL语句 -

select TagId 
from Table 
where ModuleId in (
    select ModuleId 
    from Table 
    where TagId in(A,B) 
    group by ModuleId having count(ModuleId) = 2) 
and TagId not in (A,B) 

LINQ语句 -

List<int?> temp = (from t1 in context.Table 
          where tagList.Contains(t1.TagId) 
          group t1 by t1.ModuleId into grouped 
          where grouped.Count() == tagList.Count() 
          select grouped.Key).ToList(); 

      var result = (from t2 in context.Table 
        where temp.Contains(t2.ModuleId) && !tagList.Contains(t2.TagId) 
        select t2).Distinct().ToList(); 

所以我是 -

  • 问题应该是什么这种情况下的最佳方法?
  • 如果有更好的方法,那么LINQ方法的语法是什么?

在此先感谢。

+0

为了说明一下,您希望表格中的项目属于您的tagList中包含具有* all *标签的项目的模块,但是它们本身没有与tagList中的标签相同的标签? – StriplingWarrior

回答

0

这是你的要求更简单的翻译,但它产生的SQL为您的标记列表变大变得更为复杂:

// Get items from the table 
from t in context.Table 
// ... that belong to modules 
group t by t.ModuleId into moduleTags 
// ... that have items for all the tags in the tagList 
where tagList.All(tagId => moduleTags.Any(t => t.TagId == tagId)) 
from t in moduleTags 
// ... but which themselves don't have the same tags as in the tagList. 
where !tagList.Contains(t.TagId) 
select t; 

从开始,但充分利用您“计数==计数”的把戏,这里有一个非常简单的实现,应该更好的规模:

// Get items from the table 
from t in context.Table 
// ... that belong to modules 
group t by t.ModuleId into moduleTags 
// ... that have items for all the tags in the tagList 
where moduleTags.Count(t => tagList.Contains(t.TagId)) == tagList.Count() 
from t in moduleTags 
// ... but which themselves don't have the same tags as in the tagList. 
where !tagList.Contains(t.TagId) 
select t; 

后者的实现,像你原来的SQL,假定两个表格条目和您的标记列表只有独特的条目。否则,Counts将关闭。

+0

Brilliant ..我会去第二次LINQ声明..谢谢 – Hiral