【问题标题】:Sql Select Statement with Paging c#带有分页 c# 的 Sql Select 语句
【发布时间】:2012-11-09 01:53:55
【问题描述】:

在 c# 控制器上编写 select 语句以进行分页的正确方法是什么。这是我想出的最好的方法,但我知道它不起作用,因为它在网格的第一页上显示了所有数据......请帮助

public JsonResult getData(int start, int limit)
{
  List<MyItem> items = new List<MyItem>();
  using (SqlConnection con = new       SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices1"].ConnectionString))
 {
 SqlCommand cmd = con.CreateCommand();
 cmd.CommandText = "SELECT State, Capital FROM MYDBTABLE";
 con.Open();
 SqlDataReader reader = cmd.ExecuteReader();
 while (reader.Read())
 {
   MyItem item = new MyItem();
   item.State = reader[0].ToString(); 
   item.Capital = reader[1].ToString(); 
   items.Add(item);
 }
 con.Close();

 if ((start + limit) > Myitem.Count)
 {
    limit = Myitem.Count - start;
 }
 return Json(new {  myTable = items }, JsonRequestBehavior.AllowGet);
 }
}

【问题讨论】:

  • 为什么不在查询中使用limit关键字?
  • 我很抱歉 mserioli.. 我对此完全陌生...你能给我举个例子吗...
  • 请参阅this article 并通读all of the comments
  • 嗨 Aaron... m 使用 sql 2008... 是一样的
  • 是的,我指出的文章是为 SQL Server 2005 编写的,但它仍然适用于 SQL Server 2008。

标签: c# sql sql-server-2008 select pagination


【解决方案1】:

这是我喜欢用于分页的存储过程的模板。

CREATE PROCEDURE [dbo].[StoredProcName] 
    @page_size INT
    , @page_num INT
AS
BEGIN

    SET NOCOUNT ON;

    ; WITH RESULTS AS
    (
        SELECT *
            , ROW_NUMBER() OVER (ORDER BY <order_col> DESC) AS rn
            , ROW_NUMBER() OVER (ORDER BY <order_col> ASC) AS rn_reversed
        FROM <table>
    )
    SELECT *
        , CAST(rn + rn_reversed - 1 AS INT) AS total_rows
        , CAST(CASE (rn + rn_reversed - 1) % @page_size
            WHEN 0 THEN (rn + rn_reversed - 1) / @page_size
            ELSE ((rn + rn_reversed - 1) / @page_size) + 1 
            END AS INT) AS total_pages
    FROM RESULTS a
    WHERE a.rn BETWEEN 1 + ((@page_num - 1) * @page_size) AND @page_num * @page_size
    ORDER BY rn ASC 

END

您只需将page_sizepage_num 传递给存储过程,就可以开始了。

【讨论】:

  • 谢谢 Norla...M 试图实现这个...但是 page_size 是否与“start”相同...我将这些参数从我的商店传递到 extjs 上,它被设置为 start : 0 和限制: 20...
  • @EagleFox page_size 是限制 (20) 并且 page_num 应该从 1 开始并以 1 递增。
  • 我明白了...这应该不是问题,因为 extjs 参数会自动发送...但是我总是看到几乎所有 extjs 示例中的 start 都设置为 0...让我两者都试一下,看看效果如何……谢谢诺拉
  • @EagleFox 对,extjs……如果你完全被这两个参数所困扰,你可以编辑 WHERE 子句来弥补。让我知道您是否需要帮助。
  • total_rows 和 total_pages 的计算方式有问题。似乎是由于rn_reversed。看看它产生的数字......
【解决方案2】:

您可以像这样使用 Linq 并使用 Skip()Take()

public JsonResult getData(int page, int limit)
{
    DataTable dt = new DataTable();
    using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices1"].ConnectionString))
    {
        using (SqlCommand cmd = cnn.CreateCommand())
        {
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "SELECT State, Capital FROM MYDBTABLE";
            using (SqlDataAdapter da = new SqlDataAdapter(cmd))
            {
                da.Fill(dt);
            }
        }
    }
    int start = (page * limit) - limit;
    List<MyItem> items  = (from DataRow row in dt.Rows
                           select new MyItem
                           {
                                State = row["State"].ToString(),
                                Capital = row["Capital"].ToString()
                           }).Skip(start - 1).Take(limit).ToList();
    return Json(new {  myTable = items }, JsonRequestBehavior.AllowGet);
}

【讨论】:

  • 当...谢谢 Jack Hughes...我不知道没有存储过程也可以完成
  • 这种方式也存在同样的问题。我可以得到有 20 条记录的第一页,但它不显示第二页数据,即使工具栏显示第 2 页......知道为什么杰克会这样做吗?
  • 奇怪,不知道为什么这不起作用。我对代码做了一个小的修改,而不是开始作为行位置,我将其更改为使用页码。
【解决方案3】:

我使用的基本模板是:

SELECT ROW_NUMBER(), <Rest of your columns>
FROM <Your Tables/Joins>
WHERE ROW_NUMBER() >= (@PageNum * @RowsPerPage)
AND ROW_NUMBER() < (@PageNum+1 * @RowsPerPage)

【讨论】:

  • 谢谢 KeithS... 这是直接在控制器上还是在存储过程上
  • 您可以使用这样的查询创建存储过程,然后传递参数执行它,或者您可以使用 SqlCommand 将其直接发送到服务器。如果您使用的是“vanilla”ADO.NET,就像您看起来的那样,我建议您使用存储过程。如果我这样做,我会设置一个 Linq 提供程序,比如 Entity Framework;然后查询进入编译器检查的代码并变成MyDbContext.Query&lt;MyResultObject&gt;().Select(r=&gt;r).Skip(PageNum * PerPage).Take(PerPage).ToList();
  • 对不起 KeithS.. 我没有使用实体框架...我使用的是 extjs 4.1.. 基本上带有网格分页工具栏。我很难从 db 获取分页数据
  • ROW_NUMBER() 缺少 OVER()。此外,您不能在谓词中使用ROW_NUMBER() OVER() 或任何其他排名函数。您必须创建一个派生表,其中首先计算 ROW_NUMBER()sqlfiddle.com/#!6/d41d8/10044
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 2014-11-11
  • 1970-01-01
相关资源
最近更新 更多