无法想到以所需方式对我的列表进行分组的linq方式

时间:2017-01-24 20:28:29

标签: c# linq

所以,我有我的模特:

Card
Department
PayDate
State

一个List,加载了几个项目:

1 , 25 , 12-20-2016 , A
1 , 25 , 12-20-2016 , B
1 , 25 , 12-21-2016 , D
1 , 30 , 12-20-2016 , A
1 , 30 , 12-20-2016 , X
2 , 10 , 12-20-2016 , B
2 , 15 , 12-20-2016 , A
2 , 15 , 12-21-2016 , E

我想将所有项目分组并构建此类型的结构:

Cards
   Card
      1
      Departments
         25
         PayDate
            12-20-2016
            State
               A
               B
            12-21-2016
            State
               D
         30
         PayDate
            12-20-2016
            State
               A
               X

...

它就像一个XML树,带有父标签及其子项(State是PayDate的子项,Department的PayDate子项等)。

已经尝试搞乱GroupBy(),Distinct()和嵌套的foreach,但我无法达到我想要的输出。有没有一种简单有效的方法可以做到这一点而不需要一种控制中断?

1 个答案:

答案 0 :(得分:1)

这是解决此问题的快速方法,可以帮助您顺利完成任务。基本思想是调用GroupBy将按某个键对列表进行分组,而调用select会将该选择的结果(您可以将其视为值)投影到新对象。然后,您可以将该概念重新应用于每个子组,以便按照列表的方式工作。

例如,list.GroupBy(x => x.Card)返回IEnumerable个组,每个组内部是另一个IEnumerable个模型,但这些模型都具有相同的卡。因此,我们使用相同的卡获取所有模型的IEnumerable,并请求新的Card对象(同样,我在这里只使用匿名类型),然后我们通过按部门对其余条目进行分组来获得部门等等等,直到你走到尽头。由于State没有子列表,我们只需调用pdd.Select(p => p.State),因为我们只关心状态列表的State值。

我没有为子类型创建任何类,但你可能会做类似Select(x=> new Department(x.Department))的事情。

class Model
{
    public int Card;
    public int Department;
    public string PayDate;
    public char State;

    public Model(int c, int d, string p, char s)
    {
        Card = c;
        Department = d;
        PayDate = p;
        State = s;
    }
}
var list = new List<Model>
{
    new Model(1, 25, "12 - 20 - 2016", 'A'),
    new Model(1, 25, "12 - 20 - 2016", 'B'),
    new Model(1, 25, "12 - 21 - 2016", 'D'),
    new Model(1, 30, "12 - 20 - 2016", 'A'),
    new Model(1, 30, "12 - 20 - 2016", 'X'),
    new Model(2, 10, "12 - 20 - 2016", 'B'),
    new Model(2, 15, "12 - 20 - 2016", 'A'),
    new Model(2, 15, "12 - 21 - 2016", 'E')
};

var result = list.GroupBy(x => x.Card).Select(z => 
{
    return new
    {
        card = z.Key,
        departments = z.GroupBy(d => d.Department).Select(
            dd =>
            {
                return new
                {
                    department = dd.Key,
                    payDates = dd.GroupBy(pd => pd.PayDate)
                        .Select(
                            pdd =>
                            {
                                return new {paydate = pdd.Key, states = pdd.Select(p => p.State)};
                            })
                };
            })
    };
});