使用DataSet处理分页和“延迟加载”?

时间:2011-04-07 12:32:12

标签: c# asp.net dataset

我公司使用通过存储过程专门填充的原始无类型数据集。我的任务是找到一种方法来检索非常大的结果集(分页)和获取延迟加载功能的方法(至少我认为这是延迟加载;我还在学习那些东西,说实话)所以我们不是在一个批次中撤回数万行并占用服务器资源。

我个人并不熟悉DataSet,因为我尽可能避免使用它们,我宁愿在这里完全摆脱它们,但是说“将所有内容改为使用LINQ / EF”并不是一个有效的答案,因为管理层没有商业价值(重做事情需要很长时间,所以这个想法会立即被删除。)

我是否有一些资源可以用来获得同样的功能但是使用标准的无类型数据集?

编辑:此外,我需要一个可以使用动态创建的SQL而不使用存储过程的解决方案。

4 个答案:

答案 0 :(得分:2)

您需要做的就是修改存储过程以分页结果集。这当然也意味着您必须作为参数传递某些标准,例如页码等。假设您使用的是SQL Server 05或更新版本,请查看以下内容:

http://www.codeproject.com/KB/database/PagingResults.aspx

答案 1 :(得分:2)

您需要在存储过程中实现分页。我假设你正在使用Sql Server,所以这里有一个链接:

http://www.davidhayden.com/blog/dave/archive/2005/12/30/2652.aspx

请注意,这与DataSet 本身无关。据推测,您的代码从存储过程调用生成DataSet。如果你重写你的procs来进行分页,那么你的代码将生成一个只包含所请求页面记录的DataSet。

您可以使用原始proc返回的DataSet来实现分页,方法是缓存DataSet并仅将选定的行返回给客户端(或者更准确地说,只使用DataSet的选定行来生成客户端HTML),但这样做是一个超级强者,非常糟糕的想法。

答案 2 :(得分:1)

我在asp.net 2.0网站遇到了同样的问题,没有“延迟加载”解决方案。为了对数据集进行分页,我使用了2个sprocs,这将帮助我在我正在做的每个选择上包装分页功能。

CREATE PROCEDURE [dbo].[Generic_Counting]
    @tables VARCHAR(MAX),
    @filter VARCHAR(MAX) = '1=1'    
AS
BEGIN
    SET NOCOUNT ON;


    DECLARE @strQuery VARCHAR(8000)

    SET @strQuery = ' SELECT COUNT(*) FROM '+ @tables +'
             WHERE '+ @filter 

    execute     (@strQuery)
    IF @@ERROR<>0 
    BEGIN 
        --error on generic count
        SET NOCOUNT OFF
        RETURN 10067
    END

    SET NOCOUNT OFF
    RETURN 0
END
GO

CREATE PROCEDURE [dbo].[Generic_Paging]
    @tables VARCHAR(1000),
    @pk VARCHAR(100), 
    @pageNumber INT = 1,
    @pageSize INT = 10, 
    @fields VARCHAR(MAX) = '*',
    @filter VARCHAR(MAX) = '1=1',
    @orderBy VARCHAR(MAX) = NULL
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @strQuery VARCHAR(8000) 
    DECLARE @strMinRecord VARCHAR(12);
    DECLARE @strMaxRecord VARCHAR(12);

    SET @strMinRecord = CONVERT(VARCHAR(12),((@pageNumber -1)*@pageSize + 1))  
    SET @strMaxRecord = CONVERT(VARCHAR(12), (@pageNumber * @pageSize)) 

        -- Use ROW_NUMBER function

    SET @strQuery ='
    WITH Generic_CTE As
    (
        SELECT ''RowNumber'' = ROW_NUMBER() OVER(ORDER BY ' +
        ISNULL(@orderBy,@pk) +'),' + 
        @fields + 
        ' FROM ' + @tables +
        ' WHERE ('+ @filter +')
    )
    SELECT ' + @fields + '
    FROM Generic_CTE
    WHERE RowNumber BETWEEN ' + @strMinRecord +' AND '+ @strMaxRecord 



    --print @strQuery
    execute (@strQuery)

    IF @@ERROR<>0 
    BEGIN 
        --error on generic paging
        SET NOCOUNT OFF
        RETURN 10066
    END
    SET NOCOUNT OFF 
    RETURN 0
END
GO

答案 3 :(得分:-1)

您可以查看Value List Handler模式,该模式旨在用于“客户端需要项目列表...进行演示。”列表中的项目数量未知且可能非常大在许多情况下。“

示例(在上面的链接和here中)是针对Java的,但应该很容易地转换为asp.net。