0

我想显示这样的树结构:

  • 使命1

    • 活动1
      • 项目1
    • 活动2
  • 任务2

    • 活动3
      • 项目2

但相反,我得到一个列表,该列表重复每个活动或项目的父元素,如下所示:

  • 使命1

    • 活动1
      • 项目1
  • 使命1

    • 活动2

我想将活动和项目分组在一个父(“任务”)元素下。

这是我的 LINQ 查询:

var q = from mission in _context.tMissions
                join activity in _context.tActivities on mission.id equals activity.missionId
                join project in _context.tDefaultEventTypes on activity.id equals project.activityId
                where !project.isRemoved && project.defaultCategoryId == 4
                orderby mission.name
                select CreateFrom(project);

        return q.ToList();

然后我将它绑定到一个列表并显示在页面上。这是我的aspx:

    <asp:DataList ID="dlTierTypes" runat="server">
      <ItemTemplate>
        <li><%# Eval("Activity.Mission.Name") %></li>
          <ul>
            <li><%# Eval("Activity.Name") %></li>
            <ul>
              <li><%# Eval("Name") %></li>
            </ul>
      </ItemTemplate>
    </asp:DataList>

后面的代码只是绑定它:

    public void SetTierTree(IEnumerable<DefaultEventType> tierList)
    {
      dlTierTypes.DataSource = tierList;
      dlTierTypes.DataBind();
    }

不知道如何准确解决这个问题。

编辑 - 这是我在存储库中的新功能。

    public ICollection<DefaultEventType> GetTierTree()
    {
        var q = from mission in _context.tMissions
                join activity in _context.tActivities on mission.id equals activity.missionId
                join project in _context.tDefaultEventTypes on activity.id equals project.activityId
                where !project.isRemoved && project.defaultCategoryId == 4
                orderby mission.name
                select new DefaultEventType(project.tierLevel.TryParseEnum<GanttType>(GanttType.Unknown), DefaultCategoryRepository.CreateFrom(project.tDefaultCategory))
                {
                    //t = new DefaultEventType(project.tierLevel.TryParseEnum<GanttType>(GanttType.Unknown), DefaultCategoryRepository.CreateFrom(project.tDefaultCategory)),
                    AllowNumericSuffix = project.allowNumericSuffix,
                    AttachMilestoneMoniker = project.attachMilestoneMoniker,
                    Description = project.description,
                    Id = project.id,
                    IsReadOnly = project.isReadOnly,
                    IsSticky = project.isSticky,
                    Name = project.name,
                    Sid = project.sid,
                    Style = project.style.TryParseEnum<GanttElementStyle>(GanttElementStyle.Unknown),
                    TimeStamp = project.createdDT,
                    UpdatedTimeStamp = project.updatedDT,
                    Activity = new Activity { Id = activity.id, Name = activity.name, Mission = new Mission { Id = mission.id, Name = mission.name } }
                };

        var q2 = q.GroupBy(row => row.Activity.Mission.Id)
            .Select(group => group.GroupBy(row => row.Activity.Id));

        return q2.Cast<DefaultEventType>().ToList();
    }

但我在显示页面时收到此错误:“无法从类型 'System.Collections.Generic.List 1[System.Linq.IGrouping2[System.Int32,DefaultEventType]]' 转换为类型 'DefaultEventType'。”

4

1 回答 1

1

首先,您需要调整查询。在这个例子中使用GroupBy可以极大地帮助。

只取你所拥有的,然后按任务对结果进行分组。对于每个组,按活动对任务进行分组(这需要嵌套分组,而不是顺序分组)。

var q2 = q.GroupBy(row => row.MissionID)
     .Select(group => group.GroupBy(row => row.ActivityID));

我不确定您的提供商是否可以在数据库端进行映射;AsEnumerable如果没有在需要的地方抛出一个查询。

接下来,您需要更改呈现数据的方式以反映此更改。

DataList您需要 3 个嵌套的数据列表,而不是一个。您将整个查询绑定到显示任务的外部级别,然后订阅数据绑定事件以将内部组设置为内部数据列表实例的数据源。然后,在那个内层数据列表中,显示活动并将最内层的组级别绑定到最内层DataList,这样就可以正常绑定项目名称了。

此外,您可以考虑使用 aTreeView来呈现数据结构而不是 a DataList,因为 aTreeView旨在呈现树。我不确定您是否出于某种原因需要拒绝它或者只是没有考虑它,但它可能更容易使用。如果您确实走这条路,查询仍将按照我的建议进行修改,您将不需要任何嵌套的 ASP 控件。

于 2012-12-03T19:48:39.807 回答