微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 在Linq中展平和分组复杂对象并保留null子对象

我有一个名为RouteExport的复杂对象列表,我试图根据CustomerNumber值进行展平和分组,以便返回一个看起来像的匿名对象

{ CustomerNumber = "1235",Route = route1,Section = section2,Sequence = sequence2 }

要么

{ CustomerNumber = "1234",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; }
}

每个对象都有一个CustomerNumber列表,如果它们在该路由/部分/序列中,则该列表包含客户的编号.我想根据该客户编号对每个对象进行分组.到目前为止,我一直在使用这个:

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",Section = section1,Sequence = sequence1},{ CustomerNumber = "2",Sequence = null}

解决方法

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

在第二个结束时.SelectMany(…)添加

.DefaultIfEmpty(new { rt,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,Section = (SectionExport)null,Sequence = (SequenceExport)null })))
                .ToList();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐