2008-10-06 49 views
10

我需要从我的数据访问层检索一组Widgets,按widget.Manufacturer分组,以显示在一组嵌套ASP.NET ListViews中。使用嵌套ListViews显示IGrouping <>

问题是,(据我所知)嵌套的ListView方法需要我在使用它之前对数据进行整形,而我无法找出最佳方法。我已经能够拿出迄今最好是把一个LINQ查询我的数据访问层,像这样:

var result = from widget in GetAllWidgets(int widgetTypeID) 
      group widget by widget.Manufacturer into groupedWidgets 
      let widgets = from widgetGroup in groupedWidgets 
          select widgetGroup 
      select new { Manufacturer = groupedWidgets.Key, Widgets = widgets }; 

当然,匿名类型不能被传来传去,所以那并不是”工作。定义一个自定义类来包含数据似乎是错误的方法。有什么办法可以在ASP.NET的一方执行分组吗?我使用ObjectDataSources来访问DAL。

更新:OK,我不会再创建一个匿名类型,而不是我的DAL传递一个IEnumerable<IGrouping<Manufacturer, Widget>>到ASP.NET页面,但我怎么能在我的列表视图使用?我需要(几乎或类似的东西)呈现以下HTML

<ul> 
    <li>Foo Corp. 
    <ol> 
     <li>Baz</li> 
     <li>Quux</li> 
    </ol> 
    </li> 
    <li>Bar Corp. 
    <ol> 
     <li>Thinger</li> 
     <li>Whatsit</li> 
    </ol> 
    </li> 
</ul> 

本来,我有过这样一个ListView内的ListView:

<asp:ListView ID="ManufacturerListView"> 
    <LayoutTemplate> 
     <ul> 
      <asp:Placeholder ID="itemPlaceholder" runat="server" /> 
     </ul> 
    </LayoutTemplate> 
    <ItemTemplate> 
     <li><asp:Label Text='<%# Eval("Manufacturer.Name") %>' /> 
     <li> 
     <asp:ListView ID="WidgetsListView" runat="server" DataSource='<%# Eval("Widgets") %>'> 
      <LayoutTemplate> 
       <ol> 
        <asp:PlaceHolder runat="server" ID="itemPlaceholder" /> 
      </ol> 
      </LayoutTemplate> 
      <ItemTemplate> 
       <li><asp:Label Text='<%# Eval("Name") %>'></li> 
      </ItemTemplate> 
     </asp:ListView> 
     </li> 
    </ItemTemplate> 
</asp:ListView> 

注WidgetsListView的DataSource财产是怎么本身数据绑定。如何在不重新调整数据的情况下复制此功能?

这是越来越复杂,对不起,如果我应该只是提出一个单独的问题,而不是。

回答

12

好吧,我要与我之前的声明相抵触。由于eval想要嵌套控件中的某种属性名称,我们应该可以形成这些数据。

public class CustomGroup<TKey, TValue> 
{ 
    public TKey Key {get;set;} 
    public IEnumerable<TValue> Values {get;set;} 
} 

//正是如此使用它...

IEnumerable<CustomGroup<Manufacturer, Widget>> result = 
    GetAllWidgets(widgetTypeId) 
    .GroupBy(w => w.Manufacturer) 
    .Select(g => new CustomGroup<Manufacturer, Widget>(){Key = g.Key, Values = g}; 

///以至后来......

<asp:ListView ID="ManufacturerListView"> 
<LayoutTemplate> 
    <ul> 
     <asp:Placeholder ID="itemPlaceholder" runat="server" /> 
    </ul> 
</LayoutTemplate> 
<ItemTemplate> 
    <li><asp:Label Text='<%# Eval("Key.Name") %>' /> 
    <li> 
    <asp:ListView ID="WidgetsListView" runat="server" DataSource='<%# Eval("Values") %>'> 
     <LayoutTemplate> 
      <ol> 
       <asp:PlaceHolder runat="server" ID="itemPlaceholder" /> 
      </ol> 
     </LayoutTemplate> 
     <ItemTemplate> 
      <li><asp:Label Text='<%# Eval("Name") %>'></li> 
     </ItemTemplate> 
    </asp:ListView> 
    </li> 
</ItemTemplate> 
</asp:ListView> 
3

当你使用LINQ to组,你可以得到一个强类型的对象,而该整形:

List<int> myInts = new List<int>() { 1, 2, 3, 4, 5 }; 
IEnumerable<IGrouping<int, int>> myGroups = myInts.GroupBy(i => i % 2); 
foreach (IGrouping<int, int> g in myGroups) 
{ 
    Console.WriteLine(g.Key); 
    foreach (int i in g) 
    { 
    Console.WriteLine(" {0}", i); 
    } 
} 
Console.ReadLine(); 

在你的情况,你必须:

IEnumerable<IGrouping<Manufacturer, Widget>> result = 
    GetAllWidgets(widgetTypeId).GroupBy(w => w.Manufacturer); 

这将让你从方法返回结果。

+0

感谢您的意见。我用更多的信息更新了我的原始问题。 – 2008-10-06 23:17:41

5

我刚刚花了相当长一段时间这一点。最终找到了解决方案,它非常简单。


var enumerableData = myData.Tables[0].AsEnumerable(); 
var groupedData = enumerableData.GroupBy(x => x["GroupingColumn"]); 

myParentRepeater.DataSource = groupedData; 
myParentRepeater.DataBind(); 

<asp:Repeater ID="myParentRepeater" runat="server"> 
    <ItemTemplate> 
    <h3><%#Eval("Key") %></h3> 
    <asp:Repeater ID="myChildRepeater" runat="server" DataSource='<%# Container.DataItem %>'> 
     <ItemTemplate> 
     <%#((DataRow)Container.DataItem)["ChildDataColumn1"] %> 
     <%#((DataRow)Container.DataItem)["ChildDataColumn2"] %> 
     </ItemTemplate> 
     <SeparatorTemplate> 
     <br /> 
     </SeparatorTemplate> 
    </asp:Repeater> 
    </ItemTemplate> 
</asp:Repeater> 

的eval( “钥匙”)返回分组值。 当检索子信息时,Container.DataItem是IGrouping类型,但您只需将其转换为正确的类型。

希望这可以帮助别人。

+0

在您的项目模板中,您可以用`<%#Eval(“ChildDataColumn1”)%>`替换`<%#((DataRow)Container.DataItem)[“ChildDataColumn1”]%>`。 – Armstrongest 2010-05-10 17:50:49