EF查询逻辑修正:筛选特定时间点拖车上的货物
修正EF查询逻辑:筛选特定时间点拖车上的货物
兄弟,先赶紧灌杯热姜茶躺会儿!重感冒赶交付简直是地狱难度,我帮你把这个逻辑掰明白。
先说说你原来的问题出在哪
你写的查询里,要求单条jobStop记录同时满足IsDelivery == true和IsDelivery == false——这根本不可能啊!同一行数据的同一列怎么可能同时是两个值?所以这个查询永远会返回空结果,完全不符合你的需求。
正确的逻辑思路
你要找的是**同一辆拖车(匹配TrailerId)**下:
- 至少有一条取货记录(
IsDelivery = false),且取货时间在目标日期(date.AddDays(x))之前/当天 - 同时至少有一条配送记录(
IsDelivery = true),且配送时间在目标日期之后/当天
然后把这些符合条件的取货、配送记录都筛出来。
修正后的EF代码
先定义目标日期(提前算好避免重复计算):
var targetDate = date.AddDays(x).Date;
然后用分组+子查询的方式筛选符合条件的记录:
var validJobStops = jobStops // 先限定当前要找的拖车 .Where(js => js.TrailerId == trailer.TrailerId) // 先筛出所有可能符合的取货/配送记录 .Where(js => (js.IsDelivery == false && js.JobStopDateTime.Value.Date <= targetDate) || (js.IsDelivery == true && js.JobStopDateTime.Value.Date >= targetDate) ) // 按拖车分组,确保该拖车同时有符合条件的取货和配送记录 .GroupBy(js => js.TrailerId) .Where(g => g.Any(js => js.IsDelivery == false && js.JobStopDateTime.Value.Date <= targetDate) && g.Any(js => js.IsDelivery == true && js.JobStopDateTime.Value.Date >= targetDate) ) // 把分组后的记录展开 .SelectMany(g => g);
如果你的数据量比较大,也可以先找出符合条件的拖车ID,再筛记录,性能会更好一点:
var targetDate = date.AddDays(x).Date; // 先锁定符合条件的拖车ID var validTrailerIds = jobStops .GroupBy(js => js.TrailerId) .Where(g => g.Any(js => !js.IsDelivery && js.JobStopDateTime.Value.Date <= targetDate) && g.Any(js => js.IsDelivery && js.JobStopDateTime.Value.Date >= targetDate) ) .Select(g => g.Key); // 再获取目标拖车的有效记录 var validJobStops = jobStops .Where(js => js.TrailerId == trailer.TrailerId && validTrailerIds.Contains(js.TrailerId)) .Where(js => (!js.IsDelivery && js.JobStopDateTime.Value.Date <= targetDate) || (js.IsDelivery && js.JobStopDateTime.Value.Date >= targetDate) );
额外提醒
如果JobStopDateTime可能为null,记得在判断前加空值检查(比如js.JobStopDateTime.HasValue),避免空引用异常。
内容的提问来源于stack exchange,提问作者The Angry Saxon
相关产品推荐
相关产品推荐

