繁体   English   中英

LINQ To实体COUNT个内联接

[英]LINQ To Entities INNER JOIN with COUNT

我正在尝试使用comprehension方法在LINQ中复制以下查询。 我的SQL如下:

SELECT COUNT(Post.Id), User.Id, User.Name
FROM Post  
INNER JOIN User ON Post.ModeratorId = User.Id
WHERE Post.Status IN ("Live", "Pending", "Expired")
GROUP BY User.Id, User.Name

我的LINQ查询如下,但是当没有主持人分配给帖子时,它仍然返回0计数。 请注意,Post.ModeratorId是可为空的值。

我只想要主持人的列表以及他们被主持或已经主持的帖子数量。 如何在LINQ中复制上述SQL?

    public IEnumerable<ModeratorPostViewModel> GetModeratorPostCount()
    {
        var posts = _context.Post
                       .Include(p => p.Moderator)
                       .Include(p => p.Status)
                       .Where(p => p.ModeratorId != null && p.Status.Name IN ("Live", "Pending", "Expired"))
                       .OrderBy(p => p.Moderator.Name)
                       .Select(p => new ModeratorPostViewModel 
                       {
                           Id = p.ModeratorId,
                           Name = p.Moderator.Name,
                           CountOfPosts = p.Moderator.ModeratorPosts.Count()
                       })
                       .ToList();

        // Return list
        return posts 
    }

我的模型定义如下:

public class Post
{
   int Id { get; set; }
   int StatusId { get; set; }
   string ModeratorId { get; set; }

   // Navigation properties
   public Status Status { get; set; }
   public ApplicationUser Moderator { get; set; }

   // some other other properties
}

public class ApplicationUser : IdentityUser
{
    public string Name { get; set; }

    // Navigation property
    public ICollection<Post> ModeratorPosts { get; set; }

}

我只想要主持人的列表以及主持人的数量或主持人的数量

然后将查询基于Moderator (或称为“ Moderator ”)的实体:

var statuses = new [] { "Live", "Pending", "Expired" };
var posts = _context.Moderator
    .OrderBy(m => m.Name)
    .Select(m => new ModeratorPostViewModel 
    {
        Id = m.Id,
        Name = m.Name,
        CountOfPosts = m.ModeratorPosts.Count(p => statuses.Contains(p.Status.Name))
    })
    .Where(m => m.CountOfPosts != 0)
    .ToList();

更新:我必须承认,上面的LINQ查询不能产生很好的SQL,尤其是对于最后一个Where条件。 因此,您可以使用与您的SQL查询完全相同的LINQ(您错过了GROUP BY部分):

var statuses = new [] { "Live", "Pending", "Expired" };
var posts = _context.Post
    .Where(p => p.ModeratorId != null && statuses.Contains(p.Status.Name))
    .GroupBy(p => new { Id = p.ModeratorId, Name = p.Moderator.Name })
    .Select(g => new ModeratorPostViewModel 
    {
        Id = g.Key.Id,
        Name = g.Key.Name,
        CountOfPosts = g.Count()
    })
    .OrderBy(m => m.Name)
    .ToList();

您可以按照所需的状态过滤帖子,然后进行分组

var s = new List<string>() {"Live", "Pending", "Expired"};
var grouped = db.Post.Where(x => s.Contains(x.Status)) //Fitler for the statuses
                 .GroupBy(f => f.ModeratorId, po => po,
                              (k, items) => new ModeratorPostViewModel
                                            {
                                               Name = items.FirstOrDefault().User.Name,
                                               Id=k, 
                                               CountOfPosts = items.Count()
                                            }).ToList();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM