【问题标题】:C# ASP.NET Repeater SortingC# ASP.NET 中继器排序
【发布时间】:2016-04-04 13:03:30
【问题描述】:

我正在征求关于如何使用 ASP.NET 中继器进行排序的建议。

基本上希望用户能够通过单击标题字段对重复数据进行排序。

这是我的中继器

<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>

我应该将数据存储在 ViewState 中然后进行排序吗?还是查询数据库的每次点击事件?

这是我用于填充中继器的代码

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();

}

【问题讨论】:

  • 那是旧的asp.net?与客户端代码集成如此糟糕的那个? IE。不是mvc?转向现代技术 (ASP.NET MVC) 是一种选择吗?这让事情变得容易多了,您可以在客户端做事。
  • @TomTom MVC 不是一个选项 :(
  • 如果您想在客户端这样做,请查看第三方库以替换中继器,例如datatables.net
  • 您好 Zaki,感谢您的回复。第一个链接很有帮助,但是我找到了一个类似的教程shravanti88.blogspot.co.uk/2012/03/sorting-in-repeater.html,但它并不完全适用于我的解决方案。更新帖子。

标签: c# sql asp.net


【解决方案1】:

我应该将数据存储在 ViewState 中,然后进行排序吗?还是查询数据库的每次点击事件?

没有一个正确的答案 - 如果您返回使用网络 IO 的数据库,但您总是会获得新数据,但是这些数据可能与您当前在屏幕上看到的不匹配。对ViewState vs Session vs Cache 进行一些研究,看看哪一个最能满足您的需求。其中任何一个都可以以一种易于取回的方式存储您的数据,并让您根据客户输入对其进行排序。

【讨论】:

    【解决方案2】:

    如果您使用的是 Paging,这告诉我您并不担心需要重新查询 - 因此使用 Session 似乎非常合理。

    重新查询数据库(出于排序或任何其他原因)的决定应基于几个因素来确定:

    • 数据发生变化的可能性有多大(包括添加和 删除)在用户第一次看到数据和何时 他们可能会选择重新排序 - 或者他们看到的更重要的是 更新?
    • Session 是按用户存储的。根据每个用户在服务器内存中保留的行数,这最终可能会对服务器造成负担。 Session 过期时会发生什么?
    • 重新查询数据的成本(时间、服务器处理能力等)是多少?

    我不知道这是否有帮助(尤其是最后一个问题),但您似乎正在循环通过 DataTable (ds.Tables[0].Rows) 并创建另一个 DataTable (dts)。这种处理真的有必要吗?它似乎没有做任何有用的事情——但也许这只是这个例子。 :)

    在这段代码中,我注释掉了一堆看起来没有必要的东西。如果它们在真实情况下有意义,请随时将它们带回来。

    我还添加了一个名为 isFirstTrip 的页面全局变量(您需要定义它),您需要在初始化时或在需要重新查询数据库时(例如,当用户请求时)将其设置为 1新的搜索?)。

    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();
    
    }
    

    【讨论】:

    • 你能举个例子说明如何通过会话做到这一点吗?
    • 基本上,我已将您的大部分数据库代码包装在一个 IF 中,以检查这是否是我们第一次运行 PopulateOrders 并仅在第一次访问数据库。从那时起,我们使用 Session 的副本。当您准备离开页面时,您可能还想用一些小的东西(如零长度字符串)覆盖 Session("OrderList"),这样它就不会无缘无故地留在内存中。
    • 感谢史蒂夫巴伦的例子。现在更有意义了。但是我不确定如何将上述内容应用于对数据进行排序?我正在尝试遵循示例shravanti88.blogspot.co.uk/2012/03/sorting-in-repeater.html?
    • 在这些列标题链接按钮的点击事件中,调用 PopulateOrders,并使用一个新参数指示要按哪一列排序。替换 pds.DataSource = DirectCast(session("OrderList"),DataTable).DefaultView; with pds.DataSource = New DataView(session("OrderList"),DataTable, "", SortByParameter,False);
    • 其他要考虑的事项...当您重新排序时,最好从第 1 页重新开始。在您的 Page_Load 事件中,考虑设置一个默认的排序列(和顺序?)然后跟踪它。如果用户单击 OrderItemSKUName 进行排序并且这已经是当前排序顺序,请考虑按相反顺序按同一列排序,如果这对您的用户有意义的话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    相关资源
    最近更新 更多