【问题标题】:Linq selecting range of recordsLinq 选择记录范围
【发布时间】:2011-03-07 07:17:23
【问题描述】:
    var q = (from Comments in db.tblBlogComments where Comments.blogID == this.ID orderby Comments.date descending select new {
        Comments.userID, Comments.comment, Comments.date
    });

这将返回我的所有关联记录,我如何才能最好地选择记录 #10 到 #20,这样我就不会加载任何冗余数据?

【问题讨论】:

    标签: linq sql-server-2008 pagination paging


    【解决方案1】:

    怎么样:

    var q = (
    from Comments in db.tblBlogComments 
    where Comments.blogID == this.ID 
    orderby Comments.date descending 
    select new { Comments.userID, Comments.comment, Comments.date }).Skip(10).Take(10);
    

    【讨论】:

    • 解决您对性能的担忧...这完全取决于 LINQ 提供程序,但 Skip 和 Take 通常以最有效的方式实现底层数据提供程序。例如,在 SQL 2005 / 2008 中,这可能会被转换为 ROW_NUMBER() 排名表达式。
    • 你可以在msdn.microsoft.com/en-us/library/bb399342.aspx找到实际的翻译,看起来它使用了嵌套查询。
    • @tvanfosson:也许在这个带有 LINQ-SQL 的 Skip(1) Take(1) 示例中,它使用了带有 TOP 的子查询,但我也看到了带有排名表达式的子查询。
    【解决方案2】:

    您可以在结果集上使用.Skip().Take() 方法。示例:

    var q = (from Comments in db.tblBlogComments where Comments.blogID == this.ID orderby Comments.date descending select new {
        Comments.userID, Comments.comment, Comments.date
    });
    

    然后使用:

    int pageSize = 10;
    int page = 3;
    var currentPage = q.Skip((currentPage - 1) * pageSize).Take(pageSize);
    

    然后

    foreach(var item in currentPage)
    {
        ...
    }
    

    由于 Linq 使用延迟执行,实际查询将在 foreach 循环期间创建和执行。所以 SQL 查询只会返回当前页面的记录。

    编辑:More information about this subject

    【讨论】:

    • 当有数千条记录时,这会不会效率低下?当我永远不会使用它们时,我不想将它们加载到内存中。
    • @Tom - 除非您专门将它们转储到列表或数组中,否则 linq 一次只会在内存中加载一条记录。不过,您必须通过网络传输它们。
    【解决方案3】:
    int start = 10;
    int end = 20;
    var q = (from Comments in db.tblBlogComments 
                where Comments.blogID == this.ID 
                orderby Comments.date descending 
                select new {
                              Comments.userID, 
                              Comments.comment, 
                              Comments.date
                           }).Skip(start).Take(end - start);
    

    我不确定Skip 是否会转换为在数据库中执行的 SQL,所以这可能效率不高。

    【讨论】:

    • 我假设 Comments.ID 与存储在该记录中的 ID 字段无关?
    • 是的对不起,如果我没有说清楚,但它是为了选择范围,这是为了分页,所以如果它返回 100 条记录,如果我在页面上,我只需要 20-30 条记录3. 如果这有意义的话。
    猜你喜欢
    • 2013-05-21
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多