使用 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;
}));
我正在使用 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;
}));