LINQ使用嵌套集合对多个列进行分组
本文关键字:嵌套 集合 LINQ | 更新日期: 2023-09-27 18:28:30
我正在按多列对集合进行分组。如果它们处于相同的嵌套级别,则很容易对它们进行分组:
var groupedAirProducts = airproductsPerClient.GroupBy(ac => new
{
ac.AirProduct.PassengerNameRecord,
ac.AirProduct.Flights.First().MarketingAirlineCode,
ac.AirProduct.Flights.First().FlightNo,
ac.AirProduct.Flights.First().DepartureDate
})
问题是,我不想只按第一班航班分组,但我想把所有的航班都包括在内。我想做的是:
var groupedAirProducts= airproductsPerClient.GroupBy(ac =>
{
ac.AirProduct.PassengerNameRecord,
foreach(var flight in ac.AirProduct.Flights){
flight.MarketingAirlineCode,
flight.FlightNo,
flight.DepartureDate
}
})
请注意,上面的代码只是一个想法的示例。这不是一个有效/正确的代码。我唯一知道的方法是非常丑陋和复杂。我想知道是否有一种使用LINQ的好方法,或者一种简单的方法来解决这个问题。
编辑:解释更多的预期。作为分组的结果,我希望拥有共享相同PassengerNameRecord的航空产品集合,并且属于给定航空产品的航班共享相同MarketingAirlineCode、FlightNo和DepartmentDate。我知道如何通过讨好PassengerNameRecord的集合来实现它,所以航班被包括在其中,并对其进行分组,所以我有一组共享分组属性的航空产品。然后重建受宠若惊的结构。我希望有一种方法可以通过迭代某个集合来添加groupBy属性,或者有一种合并分组集合的方法-如果有一种方式可以将集合按PassengerNameRecord分组,将集合按Flight属性分组并合并在一起,不幸的是,我怀疑是否有简单的方法可以进行这样的合并。
您可以为GroupBy
(或其他LINQ方法)实现自定义IEqualityComparer<AirClient>
。
您可以通过以下方式实现它:
public class AirClientComparer : IEqualityComparer<AirClient>
{
public bool Equals(AirClient lhs, AirClient rhs)
{
if (lhs == null || rhs == null) return false;
if(object.ReferenceEquals(lhs, rhs)) return true;
if(lhs.PassengerNameRecord != rhs.PassengerNameRecord) return false;
if(object.ReferenceEquals(lhs.AirProduct, rhs.AirProduct)) return true;
if(lhs.AirProduct == null || rhs.AirProduct == null) return false;
if(object.ReferenceEquals(lhs.AirProduct.Flights , rhs.AirProduct.Flights )) return true;
if(lhs.AirProduct.Flights.Count != rhs.AirProduct.Flights.Count) return false;
if(lhs.AirProduct.Flights.Count == 0 && rhs.AirProduct.Flights.Count == 0) return true;
return lhs.AirProduct.Flights.All(f =>
rhs.AirProduct.Flights.Any(f2 =>
f.MarketingAirlineCode == f2.MarketingAirlineCode
&& f.FlightNo == f2.FlightNo
&& f.DepartureDate == f2.DepartureDate));
}
public int GetHashCode(AirClient obj)
{
if(obj.AirProduct == null) return 0;
int hash = obj.AirProduct.PassengerNameRecord == null
? 17 : 17 * obj.AirProduct.PassengerNameRecord.GetHashCode();
unchecked
{
foreach(var flight in obj.AirProduct.Flights)
{
hash = (hash * 31) + flight.MarketingAirlineCode == null ? 0 : flight.MarketingAirlineCode.GetHashCode();
hash = (hash * 31) + flight.FlightNo == null ? 0 : flight.FlightNo.GetHashCode();
hash = (hash * 31) + flight.DepartureDate.GetHashCode();
}
}
return hash;
}
}
现在您可以在GroupBy
:中使用它
var groupedAirProducts = airproductsPerClient.GroupBy(ac => new AirClientComparer());
在这种情况下,您需要从内部表开始。内部表还需要对外部表的引用,就像你有一个一样
AirProduct
中的ICollection<Flight> Flights
您还需要Flight
内部的Airproduct
成员。
然后像这样分组你的航班(伪代码)
AirProduct.Flights.groupby( flight => new{ flight.MarketingAirlineCode,
flight.FlightNo,
flight.DepartureDate,
flight.product.PassengerNameRecord
});