简体   繁体   中英

C# ASP.NET Repeater Sorting

I am for advice on how to go about carrying out sorting using a ASP.NET repeater.

Basically want the user be able to sort the repeated data by clicking on the headers fields.

Here is my repeater

<asp:PlaceHolder runat="server" ID="phOrders">    
<table>
  <thead>
    <tr>
      <th>Date</th>          
      <th><asp:LinkButton ID="lnkOrderBy" runat="server" Text="Order Number" OnClick="lnkOrderBy_Click"></asp:LinkButton></th>          
      <th><asp:linkButton ID="lnkOrderByItem" runat="server" Text="Item" OnClick="lnkOrderByIte_Click"></asp:linkButton></th>
      <th>Size</th>          
      <th>QTY</th>
      <th>Status</th>          
    </tr>
  </thead>
  <tbody>
    <asp:Repeater ID="rprOrders" runat="server" >

      <ItemTemplate>
        <tr>
          <td><strong><%# Eval("OrderDate") %></strong></td>
          <td><%# Eval("OrderItemSKUName") %></td>
          <td><%# Eval("OrderItemSKUID") %></td>
          <td></td>
          <td><%# Eval("OrderItemUnitCount") %></td>
          <td><strong><%# Eval("OrderItemStatus") %></strong></td>              
        </tr>
      </ItemTemplate>
    </asp:Repeater>
  </tbody>
  </table>
  <div class="track-footer"></div>
 </asp:PlaceHolder>

Should I store the data in a ViewState and then carry out sorting? Or query the database for each click events?

Here is my code for populating the repeater

private void PopulateOrders()
{

  CustomerInfo ki = CustomerInfoProvider.GetCustomerInfoByUserID(CooneenHelper.GetUserImpersonisationID());
  int nKustomerID = ki.CustomerID;
  DataTable dts = new DataTable();
  dts.Columns.Add("OrderDate", typeof(string));
  dts.Columns.Add("OrderItemSKUName", typeof(string));
  dts.Columns.Add("OrderItemSKUID", typeof(string));
  dts.Columns.Add("OrderItemStatus", typeof(string));
  dts.Columns.Add("OrderItemUnitCount", typeof(string));

  QueryDataParameters qdp = new QueryDataParameters();
  qdp.Add("@CustomerID", nKustomerID);
  DataSet ds = gc.ExecuteQuery("CN_OrderList", qdp, QueryTypeEnum.StoredProcedure, true);

  foreach (DataRow dr in ds.Tables[0].Rows)
  {
    DataRow drNew = dts.NewRow();
    drNew["OrderDate"] = ValidationHelper.GetDateTime(dr["OrderDate"], DateTime.Now).ToShortDateString();
    drNew["OrderItemSKUName"] = dr["OrderItemSKUName"].ToString();
    drNew["OrderItemSKUID"] = dr["OrderItemSKUID"].ToString();
    drNew["OrderItemStatus"] = dr["OrderItemStatus"].ToString();
    drNew["OrderItemUnitCount"] = dr["OrderItemUnitCount"].ToString();
    dts.Rows.Add(drNew);
  }

  PagedDataSource pds = new PagedDataSource();
  pds.DataSource = dts.DefaultView;
  DataView view = dts.DefaultView;

  //allow paging, set page size, and current page
  pds.AllowPaging = true;
  pds.PageSize = PerPage;
  pds.CurrentPageIndex = CurrentPage;

  //show # of current page in label
  if (pds.PageCount > 1) litResults.Text += " - Showing page " + (CurrentPage + 1).ToString() + " of " + pds.PageCount.ToString();

  //disable prev/next buttons on the first/last pages
  btnPrev.Enabled = !pds.IsFirstPage;
  btnNext.Enabled = !pds.IsLastPage;

  rprOrders.Visible = true;

  rprOrders.DataSource = pds;
  rprOrders.DataBind();

}

Should I store the data in a ViewState and then carry out sorting? Or query the database for each click events?

There's not one right answer - if you go back to the database you use network IO but you always get fresh data ,however that data may not match what you currently see on the screen. Do some research on ViewState vs Session vs Cache to see which one meets your needs best. Either one of those can store your data in a way that's easy to get back and let you sort it based on client input.

If you are using Paging, that tells me that you are not concerned about the need to requery - so resorting from Session seems perfectly reasonable.

The decision to requery the database (for sorting or any other reason) should be determined based on several factors:

  • What is the likelihood that the data have changed (including adds and deletes) in between the time the user first saw the data and when they might choose to re-sort - or is it even important that they see the updates?
  • Session is a per-user store. Depending on how many rows each user is keeping in the server's memory, that could eventually tax the server. What happens when Session expires?
  • What is the cost (time, server processing power, etc) of requerying the data?

I don't know if this helps (especially with that last question) but you seem to be cycling through a DataTable (ds.Tables[0].Rows) and creating another DataTable (dts). Is that processing really necessary? It doesn't appear to be doing anything useful - but maybe that's just this example. :)

In this code, I've commented out a bunch of things which don't appear to be necessary. Feel free to bring them back if they make sense in the real situation.

I've also added a page-global variable (which you'll need to define) called isFirstTrip which you'll need to set to 1 on init or any time you need the database requeried (eg, when the user does a new search?).

private void PopulateOrders()
{
  if (isFirstTrip == 1) 
  {
    CustomerInfo ki = CustomerInfoProvider.GetCustomerInfoByUserID(CooneenHelper.GetUserImpersonisationID());
    int nKustomerID = ki.CustomerID;
    /*
    DataTable dts = new DataTable();
    dts.Columns.Add("OrderDate", typeof(string));
    dts.Columns.Add("OrderItemSKUName", typeof(string));
    dts.Columns.Add("OrderItemSKUID", typeof(string));
    dts.Columns.Add("OrderItemStatus", typeof(string));
    dts.Columns.Add("OrderItemUnitCount", typeof(string));
    */

    QueryDataParameters qdp = new QueryDataParameters();
    qdp.Add("@CustomerID", nKustomerID);
    session("OrderList") = gc.ExecuteQuery("CN_OrderList", qdp, QueryTypeEnum.StoredProcedure, true);

    /*DataSet ds = gc.ExecuteQuery("CN_OrderList", qdp, QueryTypeEnum.StoredProcedure, true);

    foreach (DataRow dr in ds.Tables[0].Rows)
    {
      DataRow drNew = dts.NewRow();
      drNew["OrderDate"] = ValidationHelper.GetDateTime(dr["OrderDate"], DateTime.Now).ToShortDateString();
      drNew["OrderItemSKUName"] = dr["OrderItemSKUName"].ToString();
      drNew["OrderItemSKUID"] = dr["OrderItemSKUID"].ToString();
      drNew["OrderItemStatus"] = dr["OrderItemStatus"].ToString();
      drNew["OrderItemUnitCount"] = dr["OrderItemUnitCount"].ToString();
      dts.Rows.Add(drNew);
    }*/
  } 
  isFirstTrip = 0;
  PagedDataSource pds = new PagedDataSource();
  pds.DataSource = DirectCast(session("OrderList"),DataTable).DefaultView;
  //pds.DataSource = dts.DefaultView;
  //DataView view = dts.DefaultView;  <- Not used

  //allow paging, set page size, and current page
  pds.AllowPaging = true;
  pds.PageSize = PerPage;
  pds.CurrentPageIndex = CurrentPage;

  //show # of current page in label
  if (pds.PageCount > 1) litResults.Text += " - Showing page " + (CurrentPage + 1).ToString() + " of " + pds.PageCount.ToString();

  //disable prev/next buttons on the first/last pages
  btnPrev.Enabled = !pds.IsFirstPage;
  btnNext.Enabled = !pds.IsLastPage;

  rprOrders.Visible = true;

  rprOrders.DataSource = pds;
  rprOrders.DataBind();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM