C# Lambda表达式实现多日期字段任务列表筛选问题
解决任务列表日期筛选的Lambda表达式实现
嘿,这个日期范围筛选的问题我之前也碰到过,尤其是用Lambda写的时候容易搞混时间段重叠的逻辑,我给你理清楚并写出具体的实现代码哈!
首先咱们先明确核心逻辑:两个时间段有重叠的判断条件——任务的时间段开始 ≤ 筛选范围的结束,且任务的时间段结束 ≥ 筛选范围的开始。这个是所有日期范围筛选的基础,记住这个就不会出错了。
先回顾下你的Task模型(我用C#示例,毕竟Lambda在LINQ里最常用):
public class Task { public DateTime AvailableDate { get; set; } // 取件开始日期 public DateTime PickupDate { get; set; } // 取件结束日期 public DateTime RequestDate { get; set; } // 配送开始日期 public DateTime DeliveryDateTo { get; set; } // 配送结束日期 }
假设用户输入的筛选日期范围是filterStartDate和filterEndDate,咱们分几种常见场景实现:
场景1:筛选取件时间段与指定范围重叠的任务
比如用户想找“2018-03-10到2018-03-20之间可以取件”的任务,Lambda写法如下:
// 先定义用户筛选的日期范围 DateTime filterStartDate = new DateTime(2018, 3, 10); DateTime filterEndDate = new DateTime(2018, 3, 20); // 筛选逻辑 var pickupEligibleTasks = tasks.Where(t => t.AvailableDate <= filterEndDate && t.PickupDate >= filterStartDate);
场景2:筛选配送时间段与指定范围重叠的任务
和取件逻辑一致,替换对应的字段即可:
var deliveryEligibleTasks = tasks.Where(t => t.RequestDate <= filterEndDate && t.DeliveryDateTo >= filterStartDate);
场景3:筛选取件或配送时间段与指定范围重叠的任务
用逻辑或把两个条件组合起来:
var eligibleTasks = tasks.Where(t => // 取件时间段符合 (t.AvailableDate <= filterEndDate && t.PickupDate >= filterStartDate) || // 配送时间段符合 (t.RequestDate <= filterEndDate && t.DeliveryDateTo >= filterStartDate));
场景4:筛选单个日期可操作的任务
如果用户只选了一个日期(比如2018-03-15),要找当天可以取件/配送的任务,只需把筛选的开始和结束都设为该日期,或者直接判断:
DateTime targetDate = new DateTime(2018, 3, 15); // 当天可自取的任务 var sameDayPickupTasks = tasks.Where(t => t.AvailableDate.Date <= targetDate.Date && t.PickupDate.Date >= targetDate.Date);
这里用.Date是为了忽略DateTime的时间部分,避免因为任务的时间是“2018-03-15 14:00”而用户选的是“2018-03-15 00:00”导致筛选遗漏。
额外优化:封装成扩展方法
如果这个筛选逻辑要多次使用,可以封装成扩展方法,让代码更简洁:
public static class TaskExtensions { public static IEnumerable<Task> FilterByPickupRange(this IEnumerable<Task> tasks, DateTime start, DateTime end) { return tasks.Where(t => t.AvailableDate <= end && t.PickupDate >= start); } public static IEnumerable<Task> FilterByDeliveryRange(this IEnumerable<Task> tasks, DateTime start, DateTime end) { return tasks.Where(t => t.RequestDate <= end && t.DeliveryDateTo >= start); } }
调用的时候就可以直接写:
var eligibleTasks = tasks.FilterByPickupRange(filterStartDate, filterEndDate);
另外要注意,如果是用EF Core等ORM框架,这些Lambda表达式会被自动转化为SQL语句,日期比较的逻辑在数据库端也能正确执行,不用额外担心。
内容的提问来源于stack exchange,提问作者Dakar2008
相关产品推荐
相关产品推荐

