2016-07-20 24 views
0

Ich versuche, die folgende Abfrage in LINQ mithilfe der Verständnismethode zu replizieren. My SQL ist wie folgt:LINQ zu Entitäten INNER JOIN mit 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 

meine LINQ-Abfrage wie folgt ist aber die gibt noch eine 0 Zählung, wenn kein Moderator zur Post zugewiesen wurde. Beachten Sie, dass eine Post.ModeratorId ein Nullwert ist.

Ich möchte nur eine Liste der Moderatoren und eine Anzahl von Post sie sind oder moderiert haben. Wie kann ich das obige SQL in LINQ replizieren?

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 
    } 

Meine Modelle sind wie folgt definiert:

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

Ihre Frage ist ein wenig unklar, aber erhalten Sie "0" für "CountOfPosts = p.Moderator.ModeratorPosts.Count()"? Oder Ihre Abfrage gibt '0'' Beiträge' zurück? –

+0

Wenn es ist, dass Ihre 'p.Moderator.ModeratorPosts.Count()' 0 ist? Versuchen Sie ein 'Include()' für dieses, sowie Ihre anderen 2 - '.Include (p => p.Moderator.ModeratorPosts)', wie ich denke, das ist eine Navigationseigenschaft auch –

+0

Zunächst einmal brauchen Sie nicht 'Include' (sie werden ignoriert) beim Projizieren. Zweitens, warum starten Sie Ihre Abfrage nicht aus der Tabelle, die Moderatoren enthält? –

Antwort

3

nur ich eine Liste der Moderatoren und eine Anzahl von Post wollen sie sind oder

dann Ihre Abfrage basieren moderiert haben auf Moderator (oder wie auch immer es heißt) Einheit:

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: Ich muss zugeben, dass die obige LINQ-Abfrage nicht eine sehr gute SQL, vor allem mit der letzten Where Bedingung. So können Sie auf die genaue LINQ Äquivalent von SQL-Abfrage zurückgreifen könnte (Sie verfehlten den GROUP BY Teil):

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

Gute Antwort und 4 Sekunden schneller mit fast der gleichen Lösung Ich schrieb –

+0

Das Post-Update ändert nicht die Lösung. Ändern Sie einfach '_context.Moderator' in' _context.ApplicationUser' (oder wie es heißt). –

+1

Sie können nach dem Auswählen eine Where-Klausel hinzufügen, um Elemente herauszufiltern, bei denen CountOfPosts == 0 –

0

Sie eine Gruppe tun kann, nachdem sie die Beiträge der Filterung durch die Zustände Sie suchen

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