简体   繁体   English

使用Linq和group by的Databind中继器

[英]Databind repeater using Linq with group by

I need to bind a repeater with hierarchical data as follows: 我需要将中继器与分层数据绑定,如下所示:

Category1
   - Item1
   - Item2
Category2
   - Item3
   - Item4

I currently have a single dataset with the items as well as the category that each item belongs to. 我目前只有一个包含项目以及每个项目所属类别的数据集。

I'm trying to learn Linq and was wondering if there was a way I can do the same using Linq? 我正在尝试学习Linq,想知道是否可以使用Linq进行相同的操作?

Below is what I tried: 以下是我尝试的方法:

var groupbyfilter = from dr in dtListing.AsEnumerable()
                            group dr by dr["Category"];
        DataTable dtFinal = dtListing.Clone();

  foreach (var x in groupbyfilter)
          x.CopyToDataTable(dtFinal, LoadOption.OverwriteChanges);


  rptList.DataSource = dtFinal;
  rptList.DataBind();

But trouble with it is it repeats category for each item. 但是麻烦的是它为每个项目重复了类别。

You'll need a repeater nested inside another. 您将需要一个嵌套在另一个中继器中的中继器。

Do a distinct on the dtlisting selecting only the category field. dtlisting仅选择类别字段,以进行区分。 Bind this to the outer repeater. 将此绑定到外部中继器。

In the 2nd repeater, select data whose where condition has category field which equals to the value that is being databound to the repeater item. 在第二个转发器中,选择条件条件具有类别字段的数据,该字段等于正在绑定到转发器项目的值。 You'd have to handle this in the repeater's onitem_databound event. 您必须在转发器的onitem_databound事件中处理此问题。

Here is an example. 这是一个例子。

<%@ Import  Namespace="System.Data" %>
      <asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
          <ItemTemplate>
              <div>
                  Category: <b><%# Container.DataItem%></b>
                  <asp:Repeater ID="Repeater2" runat="server">
                      <FooterTemplate>
                          <%="</ul>" %>
                      </FooterTemplate>
                      <HeaderTemplate>
                          <%= "<ul>"%>
                      </HeaderTemplate>
                      <ItemTemplate>
                          <li>
                              <%# ((Data.DataRow)Container.DataItem)[1] %>, <%#  ((Data.DataRow)Container.DataItem)[0] %>
                          </li>
                      </ItemTemplate>
                  </asp:Repeater>
              </div>                
          </ItemTemplate>
      </asp:Repeater>

For this sample I used a csv as my datasource, and created a datatable using it. 对于此示例,我使用csv作为数据源,并使用它创建了一个数据表。 So my codebehind looks like: 所以我的代码隐藏看起来像:

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;

public class _Default : System.Web.UI.Page
{
    DataTable csvData;
    protected void Page_Load(object sender, System.EventArgs e)
    {
        csvData = Utils.csvToDataTable("data.csv", true);
        GridView1.DataSource = csvData;
        GridView1.DataBind();

        Repeater1.DataSource =
            (from x in csvData.AsEnumerable() select x["category"]).Distinct();
        Repeater1.DataBind();
    }

    protected void Repeater1_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item |
                e.Item.ItemType == ListItemType.AlternatingItem) {
            Repeater rptr = (Repeater)e.Item.FindControl("Repeater2");
            rptr.DataSource =
                csvData.AsEnumerable().Where(x => x["category"].Equals(e.Item.DataItem));
            rptr.DataBind();
        }
    }       
}

You can either use nested repeaters like deostroll says, or specify a grouping field and have a group header in your ItemTemplate that's dynamically hidden (or rendered) every time your grouping field changes. 您既可以使用deostroll说的嵌套转发器,也可以指定分组字段,并在ItemTemplate中具有组标题,该标题在每次更改分组字段时都会动态隐藏(或呈现)。

More detail in fernan's answer at http://forums.asp.net/t/1252235.aspx 有关费尔南的更多详细信息,请访问http://forums.asp.net/t/1252235.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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