2013-04-17 2 views
2

У меня есть веб-приложение C# MVC4, которое я пытаюсь выяснить для инструкции linq. (Lambda если возможно)Linq Lambda - Самая популярная страница

У меня есть две таблицы, хиты и сообщения. Hits отслеживает все посещения каждой страницы сайта. Сообщения похожи на записи в блогах. Когда пользователь посещает сообщение, PostId записывается в таблицу Hit.

Таблицы:

Hits HitId, URL, сообщения дан

Сообщений сообщения дан, постдатировать и т.д.

Категория на сайте 'Самые популярные', который будет показывать Список самых популярных сообщений по убыванию.

Наконец, я использую IPagedList, поэтому имейте в виду, что окончательный список должен быть заказан.

Что я пробовал:

var postCount = 
    _db.Posts.Join(_db.Hits, posts => posts.PostId, hits => hits.PostId, (posts, hits) => new { posts, hits }) 
    .GroupBy(num => num.posts.PostId) 
    .OrderByDescending(gp => gp.Count()) 
    .Select(g => g.Key).ToList(); 

    var results = _db.Posts.Where(p => postCount.Contains(p.PostId)); 
    const int pageSize = 5; 
    var pageNumber = (page ?? 1); 
    return View(results.ToPagedList(pageNumber, pageSize)); 

Так postCount список по заказу сообщения дана MostViewed, который является тем, что я хочу. Однако, поскольку я использую IPagedList, я получаю эту ошибку:

The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'. 

Любая помощь приветствуется! Благодаря!

EDIT

Спасибо за каждого, кто пытается помочь.

Если добавить .ToList():

var results = _db.Posts.Where(p => all2.Contains(p.PostId)).ToList(); 

Это устраняет ошибку, но она по-прежнему теряет порядок, postCount имеет. Теперь это просто отсортировано по PostId.

Возможно, есть лучший способ сделать это?

+2

Почему вы просто не называют 'OrderBy' после' Where'? –

+0

У вас есть коллекция 'Hits' в каждом посте в EF? –

+0

Можете ли вы показать свой вызов PagedList? – cadrell0

ответ

2

Этот код выглядит ужасно сложным. Вы можете уменьшить, что один запрос просто сортирует сообщения по их подсчетам хит, как это:

var results = from post in _db.Posts 
       join hit in _db.Hits 
       on post.PostId equals hit.PostId 
       group hit by post into g 
       orderby g.Count() descending 
       select g.Key; 

return View(results.ToPagedList(page ?? 1, 5)); 

Это приведет к чему-то вроде этого:

SELECT Post.PostId, Post.PostDate, Post.Whatever, ..., COUNT(*) C 
    FROM Post 
    INNER JOIN Hit ON Post.PostId = Hit.PostId 
    GROUP BY Post.PostId, Post.PostDate, Post.Whatever, ... 
    ORDER BY C DESC 
    OFFSET @offset ROWS 
    FETCH NEXT @pageSize ROWS ONLY 

Кроме того, путем добавления .ToList() к ваш запрос, он будет извлекать все из вашей базы данных и выполнять фильтрацию в памяти, что может быть намного медленнее, в зависимости от соединения между сервером и базой данных.

+0

Большое вам спасибо. Это отлично поработало. – Ryan

1

Как насчет следующего:

var results = _db.Posts.Join(_db.Hits, posts => posts.PostId, hits => hits.PostId, (posts, hits) => new { posts, hits }) 
    .GroupBy(num => num.posts) 
    .OrderByDescending(gp => gp.Count()) 
    .Select(g => g.Key) 
    .ToList(); 
+0

Спасибо, Джои - оцените помощь. Ответ Наффина отлично поработал. – Ryan

Смежные вопросы