使用 LINQ 有选择地填充 SelectMany 中的属性?

Selectively populate properties in a SelectMany using LINQ?

我正在使用 SelectMany 进行一些数据转换。它本质上是将一些分层数据扁平化。问题是某些相关数据需要用数据缺失来表示。这是我正在做的一个例子:

var records = report.Persons.SelectMany(
            person => person.Relatives.Select(relative => new FlattenedRecord
            {
                ReportNumber = report.ReportNumber,
                ReportDate = report.ReportDate,
                PersonAge = person.Age,
                PersonSex = person.Sex,
                PersonRace = person.Race,
                RelativesAge = relative.Age,
                RelativesSex = relative.Sex,
                RelativesRace = relative.Race,
                Relationship = relative.Relationship)
            }));

这会产生类似于这样的列表:

ReportNumber|ReportDate|PersonAge|PersonSex|PersonRace|RelativeAge|RelativeSex|RelativeRace|Relationship
           1|2015-01-01|       25|    M    |    W     |    48     |     F     |      W     |   Parent
           1|2015-01-01|       25|    M    |    W     |    18     |     M     |      W     |   Sibbling
           1|2015-01-01|       25|    M    |    W     |    44     |     M     |      W     |   Parent
           1|2015-01-01|       14|    F    |    B     |    34     |     F     |      B     |   Parent
           1|2015-01-01|       16|    M    |    B     |    34     |     F     |      B     |   Parent
           1|2015-01-01|        8|    M    |    B     |    34     |     F     |      B     |   Parent

需要做的是,如果有多个人有同一个亲戚,或者一个人有多个亲戚,那么后面几行的年龄、性别、种族和关系数据需要留空。示例:

ReportNumber|ReportDate|PersonAge|PersonSex|PersonRace|RelativeAge|RelativeSex|RelativeRace|Relationship
           1|2015-01-01|       25|    M    |    W     |    48     |     F     |      W     |   Parent
           1|2015-01-01|         |         |          |    18     |     M     |      W     |   Sibbling
           1|2015-01-01|         |         |          |    44     |     M     |      W     |   Parent
           1|2015-01-01|       14|    F    |    B     |    34     |     F     |      B     |   Parent
           1|2015-01-01|       16|    M    |    B     |           |           |            |    
           1|2015-01-01|        8|    M    |    B     |           |           |            |    

但我这辈子都不知道如何做我需要它做的事情。

如果你这样做呢?

var records = report.Persons.SelectMany(
            person => new FlattenedRecord
            {
                ReportNumber = report.ReportNumber,
                PersonRace = person.Race,
                RelativesAge = person.Relatives.Count() > 1 ? null : person.Relatives.First().Age
            });
Person lastPerson = null;
Relative lastRelative = null;
var records = report.Persons.SelectMany(
    person => person.Relatives.Select(relative =>
    {
        FlattenedRecord r = new FlattenedRecord
        {
            ReportNumber = report.ReportNumber,
            ReportDate = report.ReportDate,
            PersonAge = lastPerson != person ? person.Age : "",
            PersonSex = lastPerson != person ? person.Sex : "",
            PersonRace = lastPerson != person ? person.Race : "",
            RelativesAge = lastRelative != relative ? relative.Age : "",
            RelativesSex = lastRelative != relative ? relative.Sex : "",
            RelativesRace = lastRelative != relative ? relative.Race : "",
            Relationship = lastRelative != relative ? relative.Relationship : ""
        };

        lastPerson = person;
        lastRelative = relative;

        return r;
    }));