Listview分頁

 

通過查詢結果進行分頁就是以結果集的子集處理查詢結果的過程,這樣,每次返回給用戶的只是當前頁面的數據大小。

DataAdapter對象通過重載Fill方法提供了返回當前頁面數據的功能。然而,這種方法對大數據量的查詢結果並不是最好的選擇,這是因爲:當DataAdapter用請求的結果填充DataTable或者DataSet時,數據庫返回的資源仍是全部的查詢結果,只是在返回時附加了額外的限定條件才返回了少量的記錄集的。

要使用Fill方法返回當前一頁的記錄,需要指定開始記錄startRecord,和當前頁的最大記錄數maxRecords。

下面的例子用來返回一頁爲5條記錄的第一頁的查詢結果:

[VB.NET]

Dim currentIndex As Integer = 0
Dim pageSize As Integer = 5

Dim orderSQL As String = "SELECT * FROM Orders ORDER BY OrderID"
Dim myDA As SqlDataAdapter = New SqlDataAdapter(orderSQL, nwindConn)

Dim myDS As DataSet = New DataSet()
myDA.Fill(myDS, currentIndex, pageSize, "Orders")

[C#]

int currentIndex = 0;
int pageSize = 5;

string orderSQL = "SELECT * FROM Orders ORDER BY OrderID";
SqlDataAdapter myDA = new SqlDataAdapter(orderSQL, nwindConn);

DataSet myDS = new DataSet();
myDA.Fill(myDS, currentIndex, pageSize, "Orders");

在上面的例子中,DataSet只填充了5條記錄,但返回的仍是整個Orders表。如果要達到填充幾條返回幾天的目的,在SQL語句中使用TOP和WHERE從句即可。例如:

[VB.NET]

Dim pageSize As Integer = 5

Dim orderSQL As String = "SELECT TOP " & pageSize & " * FROM Orders ORDER BY OrderID"
Dim myDA As SqlDataAdapter = New SqlDataAdapter(orderSQL, nwindConn)

Dim myDS As DataSet = New DataSet()
myDA.Fill(myDS, "Orders") 

[C#]

int pageSize = 5;

string orderSQL = "SELECT TOP " + pageSize + " * FROM Orders ORDER BY OrderID";
SqlDataAdapter myDA = new SqlDataAdapter(orderSQL, nwindConn);

DataSet myDS = new DataSet();
myDA.Fill(myDS, "Orders");

此時需要注意的是:用這種方法進行的分頁,必須自己維護記錄排序的唯一標識,爲了向下一頁請求傳遞唯一的ID,我們必須象下面那樣:

[VB.NET]
Dim lastRecord As String = myDS.Tables("Orders").Rows(pageSize - 1)("OrderID").ToString()
[C#]
string lastRecord = myDS.Tables["Orders"].Rows[pageSize - 1]["OrderID"].ToString();

下面的代碼在Table填充之前進行了清空:

[VB.NET]
currentIndex = currentIndex + pageSize

myDS.Tables("Orders").Rows.Clear()

myDA.Fill(myDS, currentIndex, pageSize, "Orders")
[C#]
currentIndex += pageSize;

myDS.Tables["Orders"].Rows.Clear();

myDA.Fill(myDS, currentIndex, pageSize, "Orders");

下面是完整的代碼: 

[C#]

using System;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Windows.Forms;

public class PagingSample: Form
{
  // Form 控件.
  Button prevBtn = new Button();
  Button nextBtn = new Button();

  static DataGrid myGrid = new DataGrid();
  static Label pageLbl = new Label();

  // 分頁變量
  static int pageSize = 10;      // 要顯示的頁數
  static int totalPages = 0;      // 總頁數
  static int currentPage = 0;      // 當前頁
  static string firstVisibleCustomer = "";  // 當前頁的第一條記錄,用來進行移動“前一頁”的定位。
  static string lastVisibleCustomer = "";    //當前頁的最後條記錄,用來進行移動“下一頁”的定位。 

  // DataSet用來綁定到DataGrid.
  static DataTable custTable;

  //初始化連接和DataAdapter.
  static SqlConnection nwindConn = new SqlConnection("Data Source=.;Integrated Security=SSPI;Initial Catalog=northwind");
  static SqlDataAdapter custDA = new SqlDataAdapter("", nwindConn);
  static SqlCommand selCmd = custDA.SelectCommand;

  public static void GetData(string direction)
  {
    // 創建返回一頁記錄的SQL語句
    selCmd.Parameters.Clear();

    switch (direction)
    {
      case "下一頁":
        selCmd.CommandText = "SELECT TOP " + pageSize + " CustomerID, CompanyName FROM Customers " +
                      "WHERE CustomerID > @CustomerId ORDER BY CustomerID";
        selCmd.Parameters.Add("@CustomerId", SqlDbType.VarChar, 5).Value = lastVisibleCustomer;
        break;
      case "前一頁":
        selCmd.CommandText = "SELECT TOP " + pageSize + " CustomerID, CompanyName FROM Customers " +
                      "WHERE CustomerID < @CustomerId ORDER BY CustomerID DESC";
        selCmd.Parameters.Add("@CustomerId", SqlDbType.VarChar, 5).Value = firstVisibleCustomer;
        break;
      default:
        selCmd.CommandText = "SELECT TOP " + pageSize + " CustomerID, CompanyName FROM Customers ORDER BY CustomerID";
        
        // 計算總頁數
        SqlCommand totCMD = new SqlCommand("SELECT Count(*) FROM Customers", nwindConn);
        nwindConn.Open();
        int totalRecords = (int)totCMD.ExecuteScalar();
        nwindConn.Close();
        totalPages = (int)Math.Ceiling((double)totalRecords / pageSize);

        break;
    }

    // 用查詢結果填充臨時表
    DataTable tmpTable = new DataTable("Customers");
    int recordsAffected = custDA.Fill(tmpTable);

    // 如果表不存在,就創建
    if (custTable == null)
      custTable = tmpTable.Clone();

    // 如果有記錄返回,就刷新表
    if (recordsAffected > 0)
    {
      switch (direction)
      {
        case "下一頁":
          currentPage++;
          break;
        case "上一頁":
          currentPage--;
          break;
        default:
          currentPage = 1;
          break;
      }

      pageLbl.Text = "第" + currentPage + "/ " + totalPages + "頁";

      // 清除行集,添加新記錄
      custTable.Rows.Clear();

      foreach (DataRow myRow in tmpTable.Rows)
        custTable.ImportRow(myRow);

      // 保存first 和 last 關鍵值
      DataRow[] ordRows = custTable.Select("", "CustomerID ASC");
      firstVisibleCustomer = ordRows[0][0].ToString();
      lastVisibleCustomer = ordRows[custTable.Rows.Count - 1][0].ToString();
    }
  }

  public PagingSample()
  {
    // 初始化控件並添加到Form
    this.ClientSize = new Size(360, 274);
    this.Text = "NorthWind 數據表";

    myGrid.Location = new Point(10,10);
    myGrid.Size = new Size(340, 220);
    myGrid.AllowSorting = true;
    myGrid.CaptionText = "NorthWind 客戶信息";
    myGrid.ReadOnly = true;
    myGrid.AllowNavigation = false;
    myGrid.PreferredColumnWidth = 150;

    prevBtn.Text = "前一頁";
    prevBtn.Size = new Size(60, 24);
    prevBtn.Location = new Point(50, 240);
    prevBtn.Click += new EventHandler(Prev_OnClick);

    nextBtn.Text = "下一頁";
    nextBtn.Size = new Size(60, 24);
    nextBtn.Location = new Point(120, 240);

    pageLbl.Text = "沒有記錄返回";
    pageLbl.Size = new Size(130, 16);
    pageLbl.Location = new Point(200, 244);

    this.Controls.Add(myGrid);
    this.Controls.Add(prevBtn);
    this.Controls.Add(nextBtn);
    this.Controls.Add(pageLbl);
    nextBtn.Click += new EventHandler(Next_OnClick);

    // 計算默認的第一頁,並進行綁定
    GetData("Default");
    DataView custDV = new DataView(custTable, "", "CustomerID", DataViewRowState.CurrentRows);
    myGrid.SetDataBinding(custDV, "");
  }

  public static void Prev_OnClick(object sender, EventArgs args)
  {
    GetData("前一頁");
  }

  public static void Next_OnClick(object sender, EventArgs args)
  {
    GetData("下一頁");
  }
}

public class Sample
{
  static void Main()
  {
    Application.Run(new PagingSample());
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章