【问题标题】:Traversing a nested LINQ query in of anonymous objects in C# view via ASP.NET MVC通过 ASP.NET MVC 在 C# 视图中遍历匿名对象的嵌套 LINQ 查询
【发布时间】:2010-01-27 14:13:55
【问题描述】:

通过 ASP.NET MVC 在 C# 视图中遍历匿名对象的嵌套 LINQ 查询

您好,进行了大量搜索和阅读,但仍需要一些具体信息。 我有以下代码:

       List<DateTime> range = getRangeCollection();

        var range = (
             from years in rangeData 
             group years by years.Year 
             into yearsData 
             select new {
                 year = yearsData.Key,
                 months = (
                     from month in yearsData 
                     group month by month.Month 
                     into monthsData
                     select new {
                         month = monthsData.Key,
                         days = (
                             from days in monthsData
                             group days by days.Day
                             into daysData
                             select new {
                                 day = monthsData.Key, 
                                 days = daysData
                             })
                     })
             }).ToList();

我可以将它作为 ViewData 属性发送到这样的视图。

    <% foreach (var date in ((IEnumerable)ViewData["range"])) { 
// another foreach needed to access date.month and loop days inside.
 %> 
 <p><%=date%></p>
  <% } %>

但我想用它来生成如下所示的 HTML:

2009
  January
    (all the days in jan)
  February
    (all the days in feb)
    ..ect
2010
  Janurary
    (all the days in jan)
  February
    ...ect

我不确定我的 LINQ 是否正确,但我正在尝试在 ASP.NET MVC 环境中遍历结果。我试图了解 IEnumerable 和 IQueryable。我在正确的轨道上吗?

【问题讨论】:

    标签: asp.net-mvc linq views


    【解决方案1】:

    根据我认为您正在尝试做的事情,我认为您可能使解决方案过于复杂。最终,编写一个小类来处理这种类型的数据结构会很酷,您希望在其中根据年份和月份聚合日期。

    我假设您想省略空的年份/月份,或者您的日期范围不太可能有间隔。您还会注意到我使用的是 IQueryable,而不是 IEnumerable。

    基本上,您需要区分范围内的年份,然后区分每年的月份。所以,给定这个数据集:

    List<DateTime> dateRange = new List<DateTime>();
    dateRange.Add(new DateTime(2009, 5, 18));
    dateRange.Add(new DateTime(2009, 5, 12));
    dateRange.Add(new DateTime(2009, 6, 22));
    dateRange.Add(new DateTime(2009, 2, 14));
    dateRange.Add(new DateTime(2009, 11, 23));
    dateRange.Add(new DateTime(2010, 5, 2));
    dateRange.Add(new DateTime(2010, 7, 17));
    dateRange.Add(new DateTime(2010, 7, 10));
    dateRange.Add(new DateTime(2009, 11, 28));
    dateRange.Add(new DateTime(2009, 11, 16));
    dateRange.Add(new DateTime(2010, 1, 30));
    dateRange.Add(new DateTime(2010, 3, 1));
    dateRange.Add(new DateTime(2010, 9, 23));
    dateRange.Add(new DateTime(2010, 5, 1));
    dateRange.Add(new DateTime(2010, 9, 4));
    ViewData["range"] = dateRange.AsQueryable();
    

    您可以通过以下方式在视图中遍历它:

    <% var range = ViewData["range"] as IQueryable<DateTime>; %>
    <% foreach (var year in range.Select(x=>x.Year)
       .Distinct()
       .OrderBy(x=>x))
    { %>
    
    <ul>
        <li><%=year %>
        <ul>
    <% foreach (var month in range.Where(x=>x.Year==year)
       .OrderBy(x=>x.Month)
       .Select(x=>x.Month)
       .Distinct()) { %>
            <li><%=(new DateTime(1900,month,1)).ToString("MMMM") %>
            <ul>
    <% foreach (var day in range.Where(x => x.Year == year && x.Month == month))
    { %>
                <li>
                <%=day.ToLongDateString() %>
                </li>
    <% } %>
            </ul>
            </li>
    <% } %>
        </ul>
        </li>
    </ul>
    

    理想情况下,您只想使用扩展方法或包装类,这样您就可以做到:

    foreach(var year in range.DistinctYears())
    

    将英文格式包裹在整数值周围的月份也会很好。

    看看你的效果如何。

    【讨论】:

    • 布里克斯顿,非常感谢!在您的帮助下,它完全符合我的需要。我觉得我所知道的关于 ASP.NET 的所有知识都开始为我联系在一起了 :) 干杯!
    【解决方案2】:

    您不能按年、月、日简单地 OrderBy() 这个列表吗?我错过了什么吗?

    range.OrderBy(r => r.Year).OrderBy(r => r.Month)...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2021-07-21
      相关资源
      最近更新 更多