如何编写LINQ查询筛选员工时段范围内的Ticket(EF Core 7)
问题描述
我正在使用EF Core 7和C#,模型中一个Employee对应多个Period和多个Ticket。现有如下实体类:
public class Employee { public string EmployeeId { get; set; } public string FullName { get; set; } public List<Period> Periods { get; set; } public List<Ticket> Tickets { get; set; } } public class Period { public int PeriodId { get; set; } public DateTime From { get; set; } public DateTime To { get; set; } public Employee Employee { get; set; } public string EmployeeId { get; set; } //FK指向Employee } public class Ticket { public string TicketId { get; set; } public DateTime CreationDate { get; set; } public string EmployeeId { get; set; } //FK指向Employee }
我需要编写LINQ查询,返回处于对应员工时段范围内的Ticket,结果需为IQueryable<Ticket>类型。我尝试的查询如下:
// 创建员工ID列表 var employeeIds = new List<string> { "9854", "4587", "2587" }; IQueryable<Ticket> result = from ticket in DbContext.Tickets where employeeIds.Contains(ticket.EmployeeId) && // 需要补充条件:工单处于对应员工的任意时段[Period.From , Period.To]内 select ticket;
请补充筛选条件,使Ticket的CreationDate落在其所属员工的任意Period的From到To区间内。
解决方案
你可以通过关联Period表来判断工单的创建时间是否落在所属员工的任意时段内,以下是两种可行的实现方式:
方式1:LINQ查询语法
直接在where条件中添加Any判断,检查当前工单对应的员工是否存在一个时段包含工单的创建日期:
var employeeIds = new List<string> { "9854", "4587", "2587" }; IQueryable<Ticket> result = from ticket in DbContext.Tickets where employeeIds.Contains(ticket.EmployeeId) && DbContext.Periods.Any(p => p.EmployeeId == ticket.EmployeeId && ticket.CreationDate >= p.From && ticket.CreationDate <= p.To) select ticket;
方式2:方法链语法
如果偏好方法链的写法,也可以这样实现:
var employeeIds = new List<string> { "9854", "4587", "2587" }; var result = DbContext.Tickets .Where(t => employeeIds.Contains(t.EmployeeId)) .Where(t => DbContext.Periods .Any(p => p.EmployeeId == t.EmployeeId && t.CreationDate >= p.From && t.CreationDate <= p.To));
说明
- 两种写法都会被EF Core正确转换为SQL查询,通过
EmployeeId关联工单和时段,判断CreationDate是否处于任意一个[From, To]区间内 - 因为使用的是
IQueryable,查询逻辑会延迟执行,直到你枚举结果(比如调用ToList())时才会发送SQL到数据库
内容的提问来源于stack exchange,提问作者Aben
相关产品推荐
相关产品推荐

