2014-10-02 65 views
1

假设我有一些书的数据是这样的:集团一个数据集与嵌套Repeater

enter image description here

而且我有喜欢SELECT * FROM BookData查询,输出其按上述格式。

我想在一个HTML <table>,这将是这个样子使用嵌套Repeater控件输出的数据,由作者将数据分组结果:

enter image description here

到目前为止,我有我的ASP .NET Web表单代码看起来像这样:

<table> 
    <asp:Repeater ID="RepeaterInner" runat="server"> 
    <ItemTemplate> 
    <tr> 
     <td><asp:TextBox Text='<%# Eval("Book") %>' /></td> 
     <td><asp:TextBox Text='<%# Eval("Author") %>' /></td> 
     <td><asp:TextBox Text='<%# Eval("PublishDate") %>' /></td> 
     <td><asp:TextBox Text='<%# Eval("Pages") %>' /></td>   
    </tr> 
    </ItemTemplate> 
    </asp:Repeater> 
</table> 

和我的身后这个代码:

protected void Page_Load(object sender, EventArgs e) 
     {   

      DataSet ds = GetData(); 
      RepeaterInner.DataSource = ds; 
      RepeaterInner.DataBind(); 

     } 

     private DataSet GetData() 
     { 
      string CS = ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString; 
      using (SqlConnection con = new SqlConnection(CS)) 
      { 
       using (SqlCommand cmd = new SqlCommand("spGetData")) 
       { 
        cmd.CommandType = CommandType.StoredProcedure; 
        cmd.Connection = con; 
        con.Open(); 
        SqlDataAdapter da = new SqlDataAdapter(); 
        da.SelectCommand = cmd; 
        DataSet ds = new DataSet(); 
        da.Fill(ds); 
        con.Close(); 
        return ds;     
       } 
      } 
     } 

最终产品,我希望它看起来像这样:

<table> 
    <asp:Repeater ID="RepeaterOuter" runat="server"> 
    <ItemTemplate> 
     <tr> 
     <td><asp:TextBox Text='<%# Eval("Author") %>' /></td> 
     </tr> 
     <asp:Repeater ID="RepeaterInner" runat="server"> 
     <ItemTemplate> 
     <tr> 
      <td><asp:TextBox Text='<%# Eval("Book") %>' /></td> 
      <td><asp:TextBox Text='<%# Eval("PublishDate") %>' /></td> 
      <td><asp:TextBox Text='<%# Eval("Pages") %>' /></td>   
     </tr> 
     </ItemTemplate> 
     </asp:Repeater>  
    </ItemTemplate> 
    </asp:Repeater> 
</table> 

但我对如何做才能使上面的发生真的很困惑。可以用我的一个存储过程生成的上面的一个DataSet完成吗?如果有任何事情,我需要为每个Repeater的事件处理程序做些什么?

谢谢。

回答

1

你的存储过程看起来只返回一个数据表。所以GetData方法或许应该返回DataTable不是DataSet

private DataTable GetData() 
{ 
    DataTable dt = new DataTable(); 
    using (SqlConnection c = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString)) 
    { 
     c.Open(); 
     using (SqlCommand cmd = new SqlCommand("spGetData", c)) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      using (SqlDataAdapter da = new SqlDataAdapter(cmd)) 
      { 
       da.Fill(dt); 
      } 
     } 
    } 
    return dt; 
} 

Servy的解决方案帮助我理解IGrouping更好。建立更多自己的想法: 您Page_Load方法:

protected void Page_Load(object sender, EventArgs e) 
{ 
    DataTable dataTbl = this.GetData(); 

    //Cast the Rows collection so we can use LINQ 
    IEnumerable<dynamic> data = dt.Rows.Cast<DataRow>() 

     // Group the DataRows by the column ["Author"] 
     .GroupBy<DataRow, String>(d => Convert.ToString(d["Author"])) 

     // GroupBy returns an IEnumerable<IGrouping<TKey, TSource>> 
     // in this case we have a String (Authors Name) and 
     // DataRows with the book information. From these IGroupings 
     // we want to return a dynamic class that has properties: 
     // - Author (string it is the .Key in the IGrouping) 
     // - Books (Collection of another dynamic class that has Book properties) 
     .Select<IGrouping<String, DataRow>, dynamic>(grp => { 
      return new { 
       Author = grp.Key, 
       // grp right now is a collection of DataRows 
       // make each row into a dynamic class that has 
       // book properties so that Eval("PropName") 
       // plays nice 
       Books = grp.Select<DataRow, dynamic>(row => { 
        return new { 
         Book = Convert.ToString(row["Book"]), 
         PublishDate = Convert.ToString(row["PublishDate"]), 
         Pages = Convert.ToString(row["Pages"]) 
        }; 
       }) 
      }; 
     }); 

    RepeaterOuter.DataSource = data; 
    RepeaterOuter.DataBind(); 
} 

页代码:

<table> 
    <asp:Repeater ID="RepeaterOuter" runat="server"> 
     <ItemTemplate> 
      <tr> 
       <td><asp:TextBox runat="server" Text='<%# Eval("Author") %>' /></td> 
      </tr> 
      <asp:Repeater ID="RepeaterInner" runat="server" DataSource='<%# Eval("Books") %>'> 
       <ItemTemplate> 
       <tr> 
        <td><asp:TextBox runat="server" Text='<%# Eval("Book") %>' /></td> 
        <td><asp:TextBox runat="server" Text='<%# Eval("PublishDate") %>' /></td> 
        <td><asp:TextBox runat="server" Text='<%# Eval("Pages") %>' /></td> 
       </tr> 
       </ItemTemplate> 
      </asp:Repeater>  
     </ItemTemplate> 
    </asp:Repeater> 
</table> 
1

您可以通过作者使用GroupBy对数据进行分组,然后你就可以在内部转发简单绑定到该组的书:

RepeaterOuter.DataSource = data.GroupBy(book => book.Author, (Author, Books) => new 
{ 
    Author, 
    Books, 
}); 

现在你已经改造您的数据转换成合适的格式,你只需要书的collectino绑定到内转发在你的标记:

<asp:Repeater ID="RepeaterInner" runat="server" DataSource='<%# Eval("Books") %>'> 
+0

什么是'在'data.GroupBy(书data' => book.Author,(作者,书籍) '?它不存在于'Page_Load'事件中 – Micro 2014-10-02 15:52:24

+0

@MicroR这是你有的数据,你想用来填充你的中继器 – Servy 2014-10-02 15:54:21

+0

我拥有的数据是在DataSet中,并且没有DataSet。 GroupBy'。那么什么对象具有'.GroupBy'? – Micro 2014-10-02 16:11:13