如何查询
Employees
和 Holidays
集合,以便即使没有找到符合其指定条件的假期,仍会返回符合其条件的员工?
public class Employee
{
public Guid Id { get; set; }
public List<Holiday> Holidays { get; set; } = [];
}
public class Holiday
{
public Guid Id { get; set; }
public Guid EmployeeId { get; set; }
public DateTime Date { get; set; }
}
我有一个方法需要:
enum IncludeHolidays { None, All, Past, Future }
Employee? GetEmployee(Guid employeeId, IncludeHolidays includeHolidays)
{
var query = ctx.Employees
.Where(e => e.Id == employee.Id)
.AsQueryable();
if (includeHoliday != IncludeHolidays.None)
{
query = query.Include(e => e.Holidays);
switch (includeHoliday)
{
case IncludeHolidays.Future:
query = query.Where(e => e.Holidays.Where(h => h.Date >= DateTime.UtcNow));
break;
case IncludeHolidays.Past:
query = query.Where(e => e.Holidays.Where(h => h.Date < DateTime.UtcNow));
break;
}
}
return query.FirstOrDefault();
}
由于嵌套的
Where
调用,上述方法无法编译。但是,我不能使用 Holidays.Any
或 Holidays.Any
,因为如果员工没有符合该条件的假期,这些将排除员工。
如何查询假期而不影响已识别的员工?
实现我想要做的事情的 SQL 查询示例可能是:
select * from "Employees" e
left join "Holidays" h on e."Id" = h."EmployeeId" and h."Date" >= current_timestamp
where e."Id" = 'employee_id';
你搞砸了
Where
和Include
。这是两件事,Include
是加载相关实体的指令,EF Core 添加了过滤这些相关实体的可能性。
更正您的查询:
Employee? GetEmployee(Guid employeeId, IncludeHolidays includeHolidays)
{
var query = ctx.Employees
.Where(e => e.Id == employee.Id)
.AsQueryable();
if (includeHoliday != IncludeHolidays.None)
{
switch (includeHoliday)
{
case IncludeHolidays.Future:
query = query.Include(e => e.Holidays.Where(h => h.Date >= DateTime.UtcNow));
break;
case IncludeHolidays.Past:
query = query.Include(e => e.Holidays.Where(h => h.Date < DateTime.UtcNow));
break;
}
}
return query.FirstOrDefault();
}
您可以将条件语句传递到包含中,在这种情况下,您可以执行如下代码片段所示的操作:
query = query.Include(e => e.Holidays.Where(x => includeHoliday != IncludeHolidays.None && (includeHoliday == IncludeHolidays.All || (includeHoliday == IncludeHolidays.Past ? x.Date < DateTime.UtcNow : x.Date >= DateTime.UtcNow))));
这也允许您删除下面的行。