简体   繁体   English

将Func表达式用作GroupBy中的参数

[英]Using a Func expression as a parameter in GroupBy

I am creating some statistics on how many employees from different departments are a member of a specific Active Directory group. 我正在创建一些统计信息,以了解来自不同部门的多少员工是特定Active Directory组的成员。 To do so, i retrive all the group members from ad and group them by Department / orglevel. 为此,我从广告中检索了所有小组成员,并按部门/组织级别对其进行了分组。

I want the result to look something like this: 我希望结果看起来像这样:

Org0 | Org1 | Org2 | Count
CFO  |      |      | 27
CFO  | AA   |      | 11
CFO  | AA   | JJ   | 11
CFO  | BB   |      | 16
CFO  | BB   | CC   |  4
CFO  | BB   | DD   | 12

I have a class OrgUnit that have the following members: 我有一个具有以下成员的OrgUnit类:

public int Employees { get; set; }
public int Consultants { get; set; }
[NotMapped]
public int Total => Employees + Consultants;
public string Org0 { get; set; }
public string Org1 { get; set; }
public string Org2 { get; set; }

I also have a class Person, which is the derrived AD User object, which contains members Org0, Org1 and Org2. 我还有一个类Person,它是派生的AD User对象,其中包含成员Org0,Org1和Org2。

To get the count of how many employees there are in each org unit / level i use GroupBy, the problem is that i cant figure out how to use a generic group by expression, so i need to have one method for each org level. 为了获得每个组织单位/级别中有多少员工的计数,我使用GroupBy,问题是我无法弄清楚如何通过表达式使用通用组,因此我需要为每个组织级别使用一种方法。 As shown below: 如下所示:

private static IEnumerable<T> GetLevel0<T>(IEnumerable<Person> persons) where T : OrgUnit, new()
{
    var level0 = persons.Where(x => !string.IsNullOrEmpty(x.Org0))
        .GroupBy(ac => new
        {
            ac.Org0
        })
        .Select(ac =>
        {
            return new T
            {
                Org0 = ac.Key.Org0,
                Consultants = ac.Count(x => x.EmpGroup.Equals("Consultant")),
                Employees = ac.Count(x => x.EmpGroup.Equals("Employee"))
            };
        });
    return level0;
}

private static IEnumerable<T> GetLevel1<T>(IEnumerable<Person> persons) where T : OrgUnit, new()
{
    var level1 = persons.Where(x => !string.IsNullOrEmpty(x.Org1))
        .GroupBy(ac => new
        {
            ac.Org0,
            ac.Org1
        })
        .Select(ac => new T
        {
            Org0 = ac.Key.Org0,
            Org1 = ac.Key.Org1,
            Consultants = ac.Count(x => x.EmpGroup.Equals("Consultant")),
            Employees = ac.Count(x => x.EmpGroup.Equals("Employee"))
        });
    return level1;
}

My question is, how can i use generics to only have one method, instead of one method GetLevel pr org level? 我的问题是,我如何才能使用泛型仅使用一种方法,而不使用一种方法GetLevel pr org level?

You can do this but with scratch and some contract, First contract is you know how many arg column is exist and base on this assumption consider number of Tuple items, In this example number of args is 3: 您可以执行此操作,但是要从头开始并有一些合同,第一个合同是您知道存在多少arg列,并基于此假设考虑Tuple项的数量,在此示例中args的数量为3:

One of properties of Tuple is equality is determined by the default object equality comparer for each component. Tuple的属性之一是相等性,由每个组件的默认对象相等性比较器确定。 [MSDN] [MSDN]

If you want Level1 then fill group with new Tuple.Create(p.Org0, null, null) and if want Level2 then group is Tuple.Create(p.Org0, p.Org1, null) and so on. 如果要Level1,则用新的Tuple.Create(p.Org0, null, null)填充组,如果要Level2,则组是Tuple.Create(p.Org0, p.Org1, null) ,依此类推。

public static IEnumerable<T> GetLevel<T>(IEnumerable<Person> persons, 
    Func<Person, Tuple<string, string, string>> group)
    where T : OrgUnit, new()
{
    var level1 = persons.Where(x => 
        !string.IsNullOrEmpty(group(x).Item2 == null ? group(x).Item1 :
        (group(x).Item3 ?? group(x).Item2)))
        .GroupBy(group)
        .Select(ac => new T
        {
            Org0 = ac.Key.Item1,
            Org1 = ac.Key.Item2,
            Org2 = ac.Key.Item3,
            Consultants = ac.Count(x => x.EmpGroup.Equals("Consultant")),
            Employees = ac.Count(x => x.EmpGroup.Equals("Employee"))
        });
    return level1;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM