Пейджинг в Entity Framework - PullRequest
       27

Пейджинг в Entity Framework

30 голосов
/ 26 июня 2009

В Entity Framework, используя LINQ to Entities, подкачка базы данных обычно выполняется следующим образом:

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

В результате TWO вызовов базы данных.

Скажите, пожалуйста, как свести его к ОДНОМУ вызову базы данных.

Спасибо.

Ответы [ 6 ]

36 голосов
/ 30 августа 2010

Что не так с двумя звонками? Это небольшие и быстрые запросы. Базы данных предназначены для поддержки множества небольших запросов.

Разработка комплексного решения для выполнения одного запроса на подкачку страниц не принесет вам большой отдачи.

8 голосов
/ 02 июля 2009

Использование Esql и сопоставление хранимой процедуры с сущностью может решить проблему. SP вернет totalRows как выходной параметр и текущую страницу как набор результатов.

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

//Return paged records

Пожалуйста, сообщите.

Спасибо.

5 голосов
/ 26 июня 2009

Хммм ... фактический вызов, который использует пейджинг, является вторым - это один вызов.

Второй вызов - определить общее количество строк - это совсем другая операция, и я не знаю, как можно объединить эти две отдельные операции в один вызов базы данных с помощью Entity Framework.

Вопрос: вам действительно нужно общее количество строк? Зачем? Это стоит второй вызов базы данных или нет?

Другой вариант, который вам нужен, - это использовать EntityObjectSource (в ASP.NET), а затем привязать его, например, к. GridView, включите AllowPaging, AllowSorting и т. д. в GridView, и пусть среда выполнения ASP.NET будет выполнять всю сложную работу по извлечению соответствующей страницы данных и ее отображению.

Марк

3 голосов
/ 04 августа 2011
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 

Нет способа получить это в один вызов, но это работает достаточно быстро.

0 голосов
/ 08 июня 2017

Эти запросы слишком малы для DBManager, и я не могу понять, почему вы хотите это сделать, в любом случае, чтобы свести его к ОДНОМУ вызову базы данных, используйте это:

var list     = EntityContext.Context.UserSet
                 .Skip(startingRecordNumber)
                 .Take(pageSize)
                 .ToList();
int totalRecords = list.Count;
0 голосов
/ 01 июня 2016

Предположим, вы хотите получить детали страницы 2 с размером страницы = 4

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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...