在实体框架中进行分页

时间:2009-06-26 15:39:24

标签: entity-framework

在Entity Framework中,使用LINQ to Entities,数据库分页通常按以下方式完成:

int totalRecords = EntityContext.Context.UserSet.Count;
var list     = EntityContext.Context.UserSet
                 .Skip(startingRecordNumber)
                 .Take(pageSize)
                 .ToList();

这导致 TWO 数据库调用。

请告诉我,如何将其减少为一个数据库电话。

谢谢。

6 个答案:

答案 0 :(得分:36)

两个电话有什么问题?它们是小而快速的查询。数据库旨在支持大量小型查询。

开发一个复杂的解决方案来进行一次分页查询不会给你带来太多回报。

答案 1 :(得分:8)

使用Esql并将存储过程映射到实体可以解决问题。 SP将返回totalRows作为输出参数,将当前页面作为结果集返回。

CREATE PROCEDURE getPagedList(
@PageNumber int,
@PageSize int,
@totalRecordCount int OUTPUT
AS

//Return paged records

请告知。

谢谢。

答案 2 :(得分:5)

嗯...使用分页的实际呼叫是第二个 - 这是一次呼叫。

第二个调用是确定总行数 - 这是一个完全不同的操作,我不知道你是否可以将这两个不同的操作组合成一个与实体框架的单个数据库调用。

问题是:你真的需要总行数吗?做什么的?是否值得再次进行数据库调用?

您将拥有的另一个选项是使用EntityObjectSource(在ASP.NET中),然后将其绑定到例如一个GridView,并在GridView上启用AllowPaging和AllowSorting等,让ASP.NET运行时处理检索相应数据页并显示它的所有细节工作。

马克

答案 3 :(得分:3)

ALTER proc [dbo].[GetNames]
    @lastRow bigint,
    @pageSize bigint,
    @totalRowCount bigint output
as
begin

select @totalRowCount = count(*) from _firstNames, _lastNames

select
    FirstName,
    LastName,
    RowNumber
from
(
    select
        fn.[FirstName] as FirstName,
        ln.[Name] as LastName,
        row_number() over( order by FirstName ) as RowNumber
    from
        _firstNames fn, _lastNames ln
) as data
where
    RowNumber between ( @lastRow + 1 ) and ( @lastRow + @pageSize )

end 

无法将此功能合并到一个电话中,但效果足够快。

答案 4 :(得分:0)

这个查询对于DBManager而言太小了,我无法理解你为什么要这样做,无论如何将它减少到一个数据库调用使用这个:

var list     = EntityContext.Context.UserSet
                 .Skip(startingRecordNumber)
                 .Take(pageSize)
                 .ToList();
int totalRecords = list.Count;

答案 5 :(得分:-1)

假设您想要使用pagesize = 4

获取第2页的详细信息
int page =2;
int pagesize=4;

var pagedDetails= Categories.Skip(pagesize*(page-1)).Take(pagesize)
.Join(Categories.Select(item=>new {item.CategoryID,Total = Categories.Count()}),x=>x.CategoryID,y=>y.CategoryID,(x,y)=>new {Category = x,TotalRows=y.Total});

输出将包含Category和TotalRows的所有详细信息。

一次数据库通话。

生成SQL

-- Region Parameters
DECLARE @p0 Int = 2
DECLARE @p1 Int = 4
-- EndRegion
SELECT [t2].[CategoryID], [t2].[CategoryName], [t2].[Description], [t2].[Picture], [t5].[value] AS [TotalRows]
FROM (
    SELECT [t1].[CategoryID], [t1].[CategoryName], [t1].[Description], [t1].[Picture], [t1].[ROW_NUMBER]
    FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY [t0].[CategoryID], [t0].[CategoryName]) AS [ROW_NUMBER], [t0].[CategoryID], [t0].[CategoryName], [t0].[Description], [t0].[Picture]
        FROM [Categories] AS [t0]
        ) AS [t1]
    WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
    ) AS [t2]
INNER JOIN (
    SELECT [t3].[CategoryID], (
        SELECT COUNT(*)
        FROM [Categories] AS [t4]
        ) AS [value]
    FROM [Categories] AS [t3]
    ) AS [t5] ON [t2].[CategoryID] = [t5].[CategoryID]
ORDER BY [t2].[ROW_NUMBER]