如何从带有子项的父对象列表中提取数据?

时间:2016-09-30 13:01:35

标签: c# linq

如果我在列表中的类中有一个列表,其中类的定义如下:

class Class1
{
    public int Id { get; set; }

    public List<Class2> Class2s { get; set; }
}

class Class2
{
    public string Name { get; set; }

    public string Value { get; set; }
}

我可以创建一个Result类的列表,其中Result是:

class Result
{
    public int Class1Id { get; set; }

    public string Name { get; set; }

    public string Value { get; set; }
}

请注意,Result类包含来自Class1Class2的值。

像这样:

var results = new List<Result>();
foreach (var class1 in class1s) //class1s is a List of Class1
{
    foreach (var class2 in class1.Class2s)
    {
        results.Add(new Result()
        {
            Class1Id = class1.Id,
            Name = class2.Name,
            Value = class2.Value,
        };
    }
}

如何通过linq查询执行此操作?

我尝试了以下内容:

IList<Result> list = class1s.Select(c => c.Class2s.Select(c2 => new Result()
{
    Class1Id = c.Id,
    Type = c2.Type,
    Name = c2.Name,
}).ToList()).ToList();

但这失败了,错误:

Cannot implicitly convert type 'System.Collections.Generic.List<System.Collections.Generic.List<Results>' to 'System.Collections.Generic.IList<Results>'. An explicit conversion exists (are you missing a cast?)

注意:

重复项不回答问题,因为当结果列表是内部类的列表并且使用内部类的属性时,它们不解决问题。

2 个答案:

答案 0 :(得分:4)

使用两个from语句,可以通过查询格式轻松地从父母和子女列表中检索数据

var results = from parent in class1s
              from child in parent.Class2s 
              select new Result {
                    Class1Id = parent.Id,
                    Name = child.Name,
                    Value = child.Value,
              };
var list=results.ToList();

以流畅的格式,您可以使用SelectMany

var list = class1s.SelectMany(parent => parent.Class2s,
                              (parent,child)=>
                                           new Result {
                                              Class1Id = parent.Id,
                                              Name = child.Name,
                                              Value = child.Value
                                          }
           ).ToList();

出于显而易见的原因,我更喜欢第一种形式

请注意,我使用接受结果选择器的SelectMany重载。没有它,我必须在第一个选择器函数中使用Select,导致更加繁琐的代码

答案 1 :(得分:2)

您可以使用以下方法以非查询格式执行此操作:

results = class1s.SelectMany(c => c.Class2s.Select(c2 => new Result()
        {
            Class1Id = c.Id,
            Name = c2.Name,
            Value = c2.Value,
        })).ToList();

请注意,它与您原来的尝试非常相似,但在SelectMany而不是class1s上使用Select