C# 具有linq ef的t-sql子查询组

C# 具有linq ef的t-sql子查询组,c#,entity-framework,linq-to-entities,C#,Entity Framework,Linq To Entities,情景: 模块1有标签A和B 模块2有标签A和B 模块3有标签A 模块4有标签B 模块5有标签A B C 在表中: ModuleId TagId 1 A 1 B 2 A 2 B 3 A 4 B 5 A 5 B 5 C 条件: 我有一个TagId的列表,例如:list tagList={A,B} 我希望所有这些tagid都属于同一个ModuleId,

情景:

  • 模块1有标签A和B
  • 模块2有标签A和B
  • 模块3有标签A
  • 模块4有标签B
  • 模块5有标签A B C
在表中:

ModuleId TagId
1         A
1         B
2         A
2         B
3         A
4         B
5         A
5         B
5         C
条件:

  • 我有一个TagId的列表,例如:list tagList={A,B}
  • 我希望所有这些tagid都属于同一个ModuleId,而不是tagid列表(即tagList)。因此,它应该返回TagId 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)
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语句-

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)
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();
List temp=(来自context.Table中的t1
其中tagList.Contains(t1.TagId)
按t1.ModuleId将t1分组为分组
其中grouped.Count()==tagList.Count()
选择grouped.Key).ToList();
var result=(来自context.Table中的t2
其中temp.Contains(t2.ModuleId)和&!tagList.Contains(t2.TagId)
选择t2).Distinct().ToList();
所以我的问题是-

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

提前感谢。

这是对您的需求的简单翻译,但它生成的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;
从这一点开始,利用您的“Count==Count”技巧,这里有一个相当简单的实现,可以更好地扩展:

// 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一样,假设表条目和标记列表都只有不同的条目。否则计数将被关闭。

为了澄清,您希望表中的项目属于模块,这些模块的项目具有标记列表中的所有标记,但这些项目本身没有与标记列表中的项目相同的标记?太棒了。。我将进行第二次LINQ声明。。谢谢