如何用C# LINQ按dateFrom/dateTo关联航班与酒店实体并覆盖全日期
用C# LINQ实现按日期关联航班与酒店数据
需求场景
现有航班(Flight)和酒店(Hotel)实体数据,需要生成一份按日期维度聚合的结构化数据:每个日期下关联覆盖该日期的航班和酒店信息,且要包含所有涉及到的日期(比如酒店预订从2023-03-01到2023-03-03,中间的2023-03-02即使没有航班也要纳入)。
给定的数据示例:
- 航班数据:2023-03-01、2023-03-03各有1班
- 酒店数据:2023-03-01至2023-03-03有1个预订
目标输出:每个日期对应包含当日的航班列表和酒店列表,无对应数据则为空数组。
实现步骤
1. 定义对应C#实体类
根据提供的JSON结构,先写出适配的C#实体类:
// 航班实体 public class Flight { public int FlightId { get; set; } public DateTime DateFrom { get; set; } public DateTime DateTo { get; set; } // 其他字段可按需保留,此处仅取核心字段 } // 酒店实体 public class Hotel { public int BookId { get; set; } public DateTime DateFrom { get; set; } public DateTime DateTo { get; set; } // 其他字段可按需保留,此处仅取核心字段 } // 最终输出的日期聚合实体 public class DailyTravelInfo { public DateTime Date { get; set; } public List<FlightSummary> Flights { get; set; } = new List<FlightSummary>(); public List<HotelSummary> Hotels { get; set; } = new List<HotelSummary>(); } // 航班摘要(仅保留需展示的字段) public class FlightSummary { public int FlightId { get; set; } } // 酒店摘要(仅保留需展示的字段) public class HotelSummary { public int BookId { get; set; } }
2. 生成完整的日期范围
先找出所有涉及的日期边界,再生成该区间内的每一天:
// 初始化模拟数据源 var flights = new List<Flight> { new Flight { FlightId = 1, DateFrom = DateTime.Parse("2023-03-01"), DateTo = DateTime.Parse("2023-03-01") }, new Flight { FlightId = 2, DateFrom = DateTime.Parse("2023-03-03"), DateTo = DateTime.Parse("2023-03-03") } }; var hotels = new List<Hotel> { new Hotel { BookId = 1, DateFrom = DateTime.Parse("2023-03-01"), DateTo = DateTime.Parse("2023-03-03") } }; // 获取所有数据的日期边界 var allStartDates = flights.Select(f => f.DateFrom).Concat(hotels.Select(h => h.DateFrom)); var allEndDates = flights.Select(f => f.DateTo).Concat(hotels.Select(h => h.DateTo)); var minDate = allStartDates.Min(); var maxDate = allEndDates.Max(); // 生成日期区间内的所有日期 var dateRange = Enumerable.Range(0, (maxDate - minDate).Days + 1) .Select(d => minDate.AddDays(d)) .ToList();
3. 用LINQ关联日期与对应数据
对每个日期筛选覆盖它的航班和酒店,组装成目标结构:
var dailyTravelInfos = dateRange.Select(date => new DailyTravelInfo { Date = date, Flights = flights.Where(f => f.DateFrom <= date && date <= f.DateTo) .Select(f => new FlightSummary { FlightId = f.FlightId }) .ToList(), Hotels = hotels.Where(h => h.DateFrom <= date && date <= h.DateTo) .Select(h => new HotelSummary { BookId = h.BookId }) .ToList() }).ToList();
4. 输出JSON格式结果
如果需要输出和示例一致的JSON,可使用System.Text.Json:
var json = System.Text.Json.JsonSerializer.Serialize(dailyTravelInfos, new System.Text.Json.JsonSerializerOptions { WriteIndented = true, PropertyNamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase }); Console.WriteLine(json);
关键说明
- 日期范围生成:确保不会遗漏任何涉及的日期,哪怕当天无航班或酒店
- 筛选逻辑:
f.DateFrom <= date && date <= f.DateTo保证日期落在航班/酒店的覆盖区间内 - 摘要类:仅保留需展示的字段,避免冗余数据
内容的提问来源于stack exchange,提问作者odin_123
相关产品推荐
相关产品推荐

