我有一个C#MVC4网络应用程序,我正在尝试查找linq语句。 (如果可能,则为Lambda)
我有两个表格,点击数和帖子数。点击数可跟踪对网站上每个页面的所有访问。帖子就像博客条目。当用户访问帖子时,PostId将记录在“命中”表中。
表格:
命中
HitId,Url,PostId
帖子
PostId,PostDate等
该网站的类别为“观看次数最多”,它将显示按点击次数降序排列的“观看次数最多的帖子”列表。
最后,我正在使用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排序的PostId列表,这是我想要的。但是,由于我使用的是IPagedList,因此出现以下错误:
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
任何帮助表示赞赏!谢谢!
编辑
感谢任何尝试提供帮助的人。
如果我添加.ToList():
var results = _db.Posts.Where(p => all2.Contains(p.PostId)).ToList();
这样可以解决该错误,但是仍然会丢失postCount的顺序。现在,它仅按PostId排序。
也许有更好的方法可以做到这一点?
最佳答案
该代码看起来非常复杂。您可以按照帖子的点击次数对帖子进行排序,从而简化为一个查询,如下所示:
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()
添加到查询中,它将从数据库中获取所有内容并在内存中进行过滤,这可能要慢得多,具体取决于服务器与数据库之间的连接。关于c# - Linq Lambda-浏览最多的页面,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16062083/