我有一个搜索视图,需要根据组织层次结构中的级别返回所有员工的分组。用户需要能够按此层次结构中的任何级别进行分组。例如,我有下拉检查表,允许为Division,Department,Section,Group选择一个或多个选项。
我在数据模型中表示组织结构的方式如下:
public class OrganizationEntity : IEntity
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int OrganizationEntityTypeId { get; set; }
[DataMember]
[ForeignKey("OrganizationEntityTypeId")]
public virtual OrganizationEntityType OrganizationEntityType { get; set; }
[DataMember]
public virtual OrganizationEntity Parent { get; set; }
public virtual ICollection<OrganizationEntity> Children { get; set; }
}
OrganizationEntityType告诉我组织层次结构中的位置。
员工只链接到一个组织实体,因此员工模型如下:
public class Employee : IEntity
{
[Key]
[DataMember]
public int Id { get; set; }
[Required]
[DataMember]
public string Name { get; set; }
[DataMember]
public int CityId { get; set; }
[DataMember]
[ForeignKey("CityId")]
public virtual City City { get; set; }
[DataMember]
public int OrganizationEntityId { get; set; }
[DataMember]
[ForeignKey("OrganizationEntityId")]
public virtual OrganizationEntity OrganizationEntity { get; set; }
}
现在,我正在尝试找出使用LINQ按组织层次结构分组的最佳方法。所以说用户选择Division 1,Division 2,All Sections,Group 1并将他们的分组设置为Divisions,我需要看到数据看起来像这样:
分部员工人数
division1 25
division2 3
如果除了分组以外的相同参数设置为Section,则数据将如下所示:
部门员工人数
第1节15
第2节3
第3节4
等等其他级别。
以下是一个示例数据集:
非常感谢任何建议。
在员工查询中添加了一个过滤器,仅包括组织级别中的那些以及下面的所有组件,现在效果很好!代码如下所示:
var employees = context.Employees.Where(o => orgEntityIds.Contains(o.OrganizationEntityId));
答案 0 :(得分:2)
LINQ可以使用GroupBy
方法执行此操作,但您必须对生成分组键的方式有点创意。这是一个粗略的想法:
Func<Employee, string> selector = (n => FindOrganizationName(n.OrganizationEntity, orgType));
Dictionary<string, int> results = employees.GroupBy(selector)
.ToDictionary(n => n.Key, n => n.Count());
其中FindOrganizationName
是一个递归函数,它爬行组织层次结构,直到找到所请求的组织类型,如下所示:
string FindOrganizationName(OrganizationEntity entity, int entityType)
{
if (entity == null)
{
return string.Empty;
}
else if (entity.OrganizationEntityTypeId == entityType)
{
return entity.Name;
}
else
{
return FindOrganizationName(entity.Parent, entityType);
}
}