Как правильно решить проблему" N+1 " + Count?


Предложите модель, как показано ниже:

class public Post
{
    public int Id {get; set;}
    public virtual ICollection<Comment> Comments {get;set;}
}

На странице сообщения / Индекс я хочу показать список сообщений с количеством комментариев каждого сообщения (а не общее количество комментариев всех сообщений).

1: Если я использую

context.Posts.Include("Comments")
Он загрузит всю сущность всех связанных комментариев , на самом деле мне нужно только количество комментариев.

2: Если я получу количество каждого поста по одному:

var commentCount = context.Entry(post)
                      .Collection(p => p.Comments)
                      .Query()
                      .Count();

Это проблема N+1.

Кто-нибудь знает правильный путь?

Спасибо ты!

2 2

2 ответа:

Нужно ли это для вашей модели представления слоя / представления? В таком случае создайте специализированную ViewModel

public class PostListView 
{
    public Post Post { get; set; }
    public int CommentsCount { get; set; }
}

И использовать запрос с проекцией:

var data = context.Posts
                  .Select(p => new PostListView
                      {
                          Post = p,
                          CommentsCount = p.Comments.Count()
                      });

И вы закончили. Если вам это нужно, вы можете сгладить свой PostListView так, чтобы он содержал свойства Post вместо сущности Post.

Как насчет чего-то вроде этого:

public class PostView
{
    public String PostName { get; set; }
    public Int32 PostCount { get; set; }
}

public static IEnumerable<PostView> GetPosts()
    {
        var context = new PostsEntities();

        IQueryable<PostView> query = from posts in context.Posts
                                     select new PostView
                                                {
                                                    PostName = posts.Title,
                                                    PostCount = posts.PostComments.Count()
                                                };

        return query;
    }

Тогда используйте что-то вроде этого:

foreach (PostView post in GetPosts())
        {
            Console.WriteLine(String.Format("Post Name: {0}, Post Count: {1}", post.PostName, post.PostCount));
        }

Должен отображать список следующим образом:

  • название поста (12)
  • название поста (1)

Etc etc