实体框架LINQ多列计数(不同)

时间:2015-01-08 20:51:20

标签: linq linq-to-sql

我不完全确定如何将以下SQL转换为LINQ Fluent API。任何帮助都会很棒

select count(distinct thread.Id) as ThreadCount, count(distinct segment.Id) as SegmentCount
from Segment 
inner join SegmentCommunicator as SegmentCommunicator
    on Segment.Id = SegmentCommunicator.SegmentId
inner join Thread
    on Thread.Id = Segment.ThreadId
where SegmentCommunicator.CommunicatorId in (94, 3540, 6226, 10767, 20945)

目前,我知道如何在2个查询中执行此操作,但对于我的生活,我无法弄清楚如何缩减为一个。任何帮助将不胜感激

        var aggregate1 = _threadProvider
                .AsQueryable()
                .SelectMany(t => t.Segments)
                .Where(s => s.SegmentCommunicators.Any(sc => communicatorIds.Contains(sc.CommunicatorId)))
                .Select(s => s.ThreadId)
                .Distinct()
                .Count();

        var aggregate2 = _threadProvider
            .AsQueryable()
            .SelectMany(t => t.Segments)
            .Where(s => s.SegmentCommunicators.Any(sc => communicatorIds.Contains(sc.CommunicatorId)))
            .Select(s => s.Id)
            .Distinct()
            .Count();

1 个答案:

答案 0 :(得分:5)

你可以使用一个" base"查询,但两个不同的计数将是单独的查询,使用尽可能小的数据集保持查询一次:

var query = _threadProvider
            .AsQueryable()
            .SelectMany(t => t.Segments)
            .Where(s => s.SegmentCommunicators.Any(sc => communicatorIds.Contains(sc.CommunicatorId)))
            .Select(s => new {s.ThreadId, s.Id})
            .Distinct()
            .ToList();

var aggregate1 = query.Select(s => s.ThreadId)
                      .Distinct()
                      .Count();

var aggregate2 = query.Select(s => s.Id)
                      .Distinct()
                      .Count();    

可能可以在一个查询中使用GroupBy来执行此操作:

var query = _threadProvider
            .AsQueryable()
            .SelectMany(t => t.Segments)
            .Where(s => s.SegmentCommunicators.Any(sc => communicatorIds.Contains(sc.CommunicatorId)))
            .GroupBy(s => 1)  
            .Select(g => new 
                {
                    ThreadCount  = g.Select(s => s.ThreadId.Distinct().Count()), 
                    SegmentCount = g.Select(s => s.Id.Distinct().Count()), 
                });

但我怀疑底层查询提供程序是否会支持它(最好将它转换为两个子查询)。

请注意,任何查询都不会像原始SQL一样快,因为SQL可以在将结果返回给Linq之前优化查询。