在C#中使用LINQ用于分页结果

时间:2012-11-23 12:07:21

标签: c# jquery pagination

我正在寻找一种模式的设计解决方案,我将不得不在我正在设计的网站中重复这么多。它将是ASP.NET MVC前端,C#WCF Web服务使用NHibernate连接到SQL数据库。

这是一个社交网站,所以想象facebook在这里得到一个概念性的想法。我正在寻找的是返回大型数据集的分页结果的高效且高效的方式,例如用户可能有150封电子邮件。我希望一次返回10个,具体取决于它们所在的页面,显然只返回与页面相关的10个,而不是必须将所有150个项目加载到内存中,并且一次只显示10个,因为我认为用户体验会与更快的初始加载相比,更改页面的延迟稍长一些。毕竟你什么时候看6个月大的电子邮件?通常的情况是你只关心结果的第一页。类似地,用户自上次登录以来可能已经进行了多次交互(例如,您的通知在Facebook上提供),但我再次只想一次加载n个结果,但在这种情况下,而不是拥有页面,您可以单击“显示更多”按钮,然后可以获取下一个N个结果,使用另一个“显示更多”链接显示它们,依此类推,您可以一直点击直到到达数据集的末尾。我可以想象他们都会使用相同的设计,因为它们在技术上都是分页结果,只是具有不同的UI输出和流量。

任何人都可以为一个好的设计提供一些建议,请记住我的数据检索是使用NHibernate Queryable还是Enumerables?我是否希望在一次点击中从DB加载所有数据,然后使用interator模式仅从服务层返回N行,保持服务器内存中保留的其余列表在用户会话上下文中打开,如果我做的话另一个调用来检索接下来的N行,它将保持原位并继续返回N行直到迭代器完成,或者最好是简单地从数据库中检索N行并返回那些,在会话上下文中什么也不保留?我可以看到如何从Queryable返回前10个结果

var results = (from email in emails where email.UserId = userId).Take(10);

但我不确定这是多么有效,这是最快的方式吗?而且我不知道如何从某个位置开始,这将始终只返回前10个,而不是第二个10,或第三个10等。

所以我有点不确定最好的方法是如何进行,并希望得到类似的人的一些指示和建议。牢记我的网站性能将是至关重要的,因此用户体验需要非常敏锐和互动,并带来令人耳目一新的新结果。基本上,如果你试图模拟facebook新闻源/墙 - 你将如何使用上述架构实现它?

谢谢!

3 个答案:

答案 0 :(得分:4)

您可以将SkipTake结合使用:

var results = (from email in emails where email.UserId = userId)
              .Skip((currentPage - 1) * 10)
              .Take(10);

关于Web服务:您真的应该使它成为无状态Web服务。您可以使用ASP.NET Web API。这使您可以构建RESTful Web服务。

答案 1 :(得分:2)

  

我是否想加载所有内容...

绝对不是,您只想下拉您需要的记录,而不是您可能所需的记录。

  

...使用interator模式只从服务层返回N行,保持服务器内存中保留的其余列表在用户会话上下文中打开...

可扩展性随着这个想法而出现在窗外。

  

...或者最好只是从数据库中检索N行并返回那些,在会话上下文中什么也不保留?

现在你开始走上正确的轨道......

一般情况下,您希望让数据库尽可能多地进行查询,即您不想访问数据库,然后必须进一步查询结果(但是,并非总是如此)避免)。换句话说,您希望将繁重的工作(如果不是全部)委托给数据库。

你提到你正在使用NHibernate这是一个非常强大的ORM。好消息是,在查询优化/缓存数据方面为您做了很多工作。像现在的大多数ORM一样,NHibernate使用延迟执行查询,所以请注意像过早地访问数据库&选择何时加载数据而不是执行多个查询。 NHibernate还有很多值得学习的地方,如果你还没有,那么在潜水之前花点时间阅读它会让你省去很多麻烦。

  

牢记我的网站性能将是至关重要的,因此用户体验需要非常敏锐和互动,并带来令人耳目一新的新结果

就性能而言(我假设您的意思是页面加载速度),您只是想要对您的网站进行调整,即加载需要加载页面的内容,然后将其余部分放在后台&动态更新页面。为了实现“令人耳目一新的新成果”#34;您需要查看polling服务器并提取新数据。我非常确定Facebook使用了一种名为long polling的技术,该技术基本上将一个活动请求与服务器保持一段时间,这样数据就会立即发生并立即发生#34;轮询是一个不同的球赛,但它是关于打击服务器负载的平衡与如何"新鲜"数据需要 - 你需要自己决定的东西,答案通常取决于数据的类型与服务器的硬件功能。

答案 2 :(得分:0)

有一些关于它的链接(like this),但我喜欢this guy approach。我不知道我是否会使用他的PagedQueryable,但他的IPageableIPagedEnumerablePagedEnumerable非常有趣。此外,他的项目介绍页面可能会给你一些关于如何推出自己的分页的想法。