在Linq中弄平和组的复杂物体,并保留无效的儿童



我有一个复杂的对象的列表,称为 RouteExport,我试图根据 CustomerNumber值来平坦和组,以便它返回一个看起来像

的匿名对象
{ CustomerNumber = "1235", Route = route1, Section = section2, Sequence = sequence2 } 

{ CustomerNumber = "1234", Route = route1, Section = null, Sequence = null }

模型看起来像这样:

public class RouteExport
{
    public string Name { get; set; }
    public string Term { get; set; }
    public List<string> CustomerNumbers { get; set; }
    public List<SectionExport> Sections { get; set; }
}
public class SectionExport
{
    public string Name { get; set; }
    public List<string> CustomerNumbers { get; set; }
    public List<SequenceExport> Sequences { get; set; }
}
public class SequenceExport
{
    public string Name { get; set; }
    public List<string> CustomerNumbers { get; set; }
}

每个对象都有一个自定义列表,该列表包含客户的电话号码,如果它们处于该路由/部分/序列中。我想根据该客户编号将每个对象组成。到目前为止,我一直在使用:

var flattendExport = exportViewModel.ExportContainer.Routes
            .SelectMany(rt => rt.Sections
                .SelectMany(sec => sec.Sequences
                    .SelectMany(seq => seq.CustomerNumbers
                        .Select(custNum => new { rt, sec, seq, custNum })))).ToList();

使对象变平但不会按CustomerNumber分组,也不会为部分或序列返回null。

我如何进行查询,该查询将返回一个由每个对象的CustomerNumbers组返回组的列表,如果它们不在部分或序列中,则返回null

用测试用例更新

我没有充分地表达原始问题,因此进行了一些编辑。我想对客户的编号进行分组,以便此数据:

var data = new List<RouteExport>
{
    new RouteExport
    {
        CustomerNumbers = new List<string> { "1", "2" },
        Sections = new List<SectionExport>
        {
            new SectionExport()
            {
                CustomerNumbers = new List<string> { "1" },
                Sequences = new List<SequenceExport> {
                    new SequenceExport()
                    {
                        CustomerNumbers = new List<string> { "1" }
                    }
                }
            }
        }
    }
};

返回以下结果:

{ CustomerNumber = "1", Route = route1, Section = section1, Sequence = sequence1},
{ CustomerNumber = "2", Route = route1, Section = null, Sequence = null}

您可以使用Linq的DefaultIfEmpty插入Sections集合为空时所需的空值。请参阅https://msdn.microsoft.com/en-us/library/bb355419(v = vs.110(.aspx

在第二个.SelectMany(...)的末尾添加:

.DefaultIfEmpty(new { rt, null, null, cystNum })

``对于每个没有部分的路由,创建一个虚拟结果''。

编辑:鉴于您更改的要求,它看起来像这样:

 var res = data.SelectMany(r => r.CustomerNumbers
            .SelectMany(c => r.Sections.Where(s => s.CustomerNumbers.Contains(c))
                .SelectMany(s => s.Sequences
                  .Select(seq => new { CustomerNumber = c, Route = r, Section = s, Sequence = seq }))
                .DefaultIfEmpty(new { CustomerNumber = c, Route = r, Section = (SectionExport)null, Sequence = (SequenceExport)null })))
                .ToList();

最新更新