2016-07-20 13 views
0

私はLINQで次のクエリを理解方法を使って複製しようとしています。次のように私のSQLは、次のようにLINQ To Entities INNER JOIN with COUNT

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はnull値であることに注意してください。

私は、司会者のリストと、自分が管理している、または司会している投稿のカウントが必要です。 上記のSQLをLINQでどのように複製できますか?

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; } 

} 
+0

あなたの質問は少し不明ですが、 'CountOfPosts = p.Moderator.ModeratorPosts.Count()'に '0'を得ていますか?または、あなたのクエリは '0'' posts'を返していますか? –

+0

'p.Moderator.ModeratorPosts.Count()'が0の場合は?他の2 - '.Include(p => p.Moderator.ModeratorPosts)'と同様に 'Include()'を試してみてください。これはナビゲーションプロパティでもあると思いますので、まずは –

+0

投影時に 'Include'(無視されます)。次に、モデレーターを含むテーブルからクエリを開始するのはなぜですか? –

答えて

3

私はモデレータのみのリストをしたいと、彼らはあるか

を緩和しているポストの数は、その後、あなたのクエリをベースに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(); 

UPDATE:上記のLINQクエリは、特に最後のWhere条件で非常に優れたSQLを生成しないことを認めなければなりません。つまり、あなたのSQLクエリ(あなたがGROUP BY一部を逃した)の正確なLINQと同等に頼るかもしれません:

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(); 
+0

丁寧な応答と4秒の速さで、私が書いていたのとまったく同じソリューションです。 –

+0

ポストアップデートではソリューションが変更されません。 '_context.Moderator'を' _context.ApplicationUser'(あるいはそれが呼び出される方法)に変更するだけです。 –

+1

CountOfPosts == 0 –

0

あなたは

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(); 
を探している状態での投稿をフィルタリングした後、グループを行うことができます