如何更改 CROSS APPLY 表达式中的 WHERE 子句
How to change WHERE clause in CROSS APPLY expression
我正在尝试从如下查询中获取 DTO
对象:
public async Task<IEnumerable<CalendarRoomsDto>> GetCalendarByRoomsAsync(DateTime DateValue)
{
return await (from room in DbContext.ClinicRooms
from app in DbContext.ClientAppointments
.Where(app => app.ClinicRoomId == room.Id && DateValue.Date == app.StartDate.Value.Date && app.ClientId != null)
from client in DbContext.Clients
.Where(client => client.Id == app.ClientId)
from spec in DbContext.Specialists
.Where(spec => spec.Id == app.SpecialistId)
from cash in DbContext.ClientCashIncome
.Where(cash => cash.ClientAppointmentId == app.Id)
.DefaultIfEmpty()
from proc in DbContext.ClientAppointmentResultProcedures
.Where(proc => proc.ClientAppointmentResultId == app.Id)
.DefaultIfEmpty()
select new CalendarRoomsDto
{
Id = room.Id,
Name = room.Name,
Number = room.Number,
RoomAppointments = room.Appointments.Select(s =>
new AppointmentRoomsDto
{
Id = app.Id,
AlreadyInClinic = app.AlreadyInClinic,
AppointmentType = app.AppointmentType,
BranchId = app.BranchId,
ClientId = app.ClientId,
ClientName = client.Name,
ClientNotified = app.ClientNotified,
Start = app.StartDate,
End = app.EndDate,
HasPayments = cash.Amount != null,
HasProcedures = proc.ClientAppointmentResultId != null,
InsuredAccidentType = app.InsuredAccidentType,
Ordinality = app.Ordinality,
Reason = app.Reason,
SpecialistId = app.SpecialistId,
SpecialistName = spec.Name
}).Where(app => DateValue.Date == app.Start.Value.Date),
})
.AsNoTracking()
.ToListAsync();
}
此查询转换为 SQL:
SELECT [c].[id],
[c].[name],
[c].[number],
[t].[id],
[c1].[id],
[s].[id],
[t0].[id],
[t0].[already_in_clinic],
[t0].[appointment_type],
[t0].[branch_id],
[t0].[client_id],
[t0].[name],
[t0].[client_notified],
[t0].[start_date],
[t0].[end_date],
[t0].[c],
[t0].[c0],
[t0].[insured_accident_type],
[t0].[ordinality],
[t0].[reason],
[t0].[specialist_id],
[t0].[name0],
[t0].[id0]
FROM [clinic_rooms] AS [c]
INNER JOIN (SELECT [c0].[id],
[c0].[already_in_clinic],
[c0].[app_target_id],
[c0].[appointment_date_changed],
[c0].[appointment_files],
[c0].[appointment_source],
[c0].[appointment_type],
[c0].[barcode],
[c0].[branch_id],
[c0].[call],
[c0].[cancel_date],
[c0].[cancel_reason],
[c0].[cancel_type_person],
[c0].[card_number],
[c0].[client_id],
[c0].[client_notified],
[c0].[clinic_room_id],
[c0].[color],
[c0].[create_account_id],
[c0].[create_date],
[c0].[end_date],
[c0].[followup_visit_id],
[c0].[how_did_you_know_id],
[c0].[insurance_company_discount],
[c0].[insurance_guarantor],
[c0].[insurance_policy_id],
[c0].[insurance_specialist],
[c0].[insurance_specialist_phone],
[c0].[insured_accident_type],
[c0].[is_cash_printed],
[c0].[is_synevo_added],
[c0].[is_synevo_checked],
[c0].[is_synevo_validated],
[c0].[ordinality],
[c0].[possible_app_date],
[c0].[priority],
[c0].[reason],
[c0].[show_on_additional_spesialist_dashboard],
[c0].[small_notes],
[c0].[sms_sent],
[c0].[specialist_id],
[c0].[specialist_notified],
[c0].[specialist_recommendation_id],
[c0].[start_date],
[c0].[status],
[c0].[update_account_id],
[c0].[update_date],
[c0].[vendor_order_id],
[c0].[vendor_order_response_json],
[c0].[vendor_order_status],
[c0].[zoom_meeting_url]
FROM [client_appointments] AS [c0]
WHERE ( Cast('2020-08-03' AS DATETIME) =
CONVERT(DATE, [c0].[start_date]) )
AND [c0].[client_id] IS NOT NULL) AS [t]
ON [c].[id] = [t].[clinic_room_id]
INNER JOIN [clients] AS [c1]
ON [t].[client_id] = [c1].[id]
INNER JOIN [specialists] AS [s]
ON [t].[specialist_id] = [s].[id]
LEFT JOIN [client_cash_income] AS [c2]
ON [t].[id] = [c2].[client_appointment_id]
LEFT JOIN [client_appointment_result_procedures] AS [c3]
ON [t].[id] = [c3].[client_appointment_result_id]
OUTER apply (SELECT [t].[id],
[t].[already_in_clinic],
[t].[appointment_type],
[t].[branch_id],
[t].[client_id],
[c1].[name],
[t].[client_notified],
[t].[start_date],
[t].[end_date],
CASE
WHEN [c2].[amount] IS NOT NULL THEN Cast(1 AS BIT)
ELSE Cast(0 AS BIT)
END AS [c],
CASE
WHEN [c3].[client_appointment_result_id] IS NOT
NULL THEN
Cast(1 AS BIT)
ELSE Cast(0 AS BIT)
END AS [c0],
[t].[insured_accident_type],
[t].[ordinality],
[t].[reason],
[t].[specialist_id],
[s].[name] AS [name0],
[c4].[id] AS [id0]
FROM [client_appointments] AS [c4]
WHERE ( Cast('2020-08-03' AS DATETIME) =
CONVERT(DATE, [t].[start_date]) )
AND ( [c].[id] = [c4].[clinic_room_id] )) AS [t0]
ORDER BY [c].[id],
[t].[id],
[c1].[id],
[s].[id],
[t0].[id0]
除了最后一个 WHERE
子句外,这几乎就是我想要的。它将日期与 [t].[start_date]
列进行比较,在我的情况下,它会导致数据重复( OUTER APPLY
适用于 '2020-08-03'
天的记录除外)。
我应该怎么做才能在这个表达式中得到 [c4].[start_date]
?那会给我我想要的结果。
提前致谢!
我看到您正在获取一个房间的所有预约,无论日期如何。请满足以下条件并尝试一次
在您的 linq 中修改以下逻辑
RoomAppointments = room.Appointments.Select(s =>
至
RoomAppointments = room.Appointments.where(y => y.StartDate.Value.Date == DateValue.Date).Select(s =>
不确定约会中 Start_Date 的 属性 名称是否正确,请在更新代码之前更正。
我正在尝试从如下查询中获取 DTO
对象:
public async Task<IEnumerable<CalendarRoomsDto>> GetCalendarByRoomsAsync(DateTime DateValue)
{
return await (from room in DbContext.ClinicRooms
from app in DbContext.ClientAppointments
.Where(app => app.ClinicRoomId == room.Id && DateValue.Date == app.StartDate.Value.Date && app.ClientId != null)
from client in DbContext.Clients
.Where(client => client.Id == app.ClientId)
from spec in DbContext.Specialists
.Where(spec => spec.Id == app.SpecialistId)
from cash in DbContext.ClientCashIncome
.Where(cash => cash.ClientAppointmentId == app.Id)
.DefaultIfEmpty()
from proc in DbContext.ClientAppointmentResultProcedures
.Where(proc => proc.ClientAppointmentResultId == app.Id)
.DefaultIfEmpty()
select new CalendarRoomsDto
{
Id = room.Id,
Name = room.Name,
Number = room.Number,
RoomAppointments = room.Appointments.Select(s =>
new AppointmentRoomsDto
{
Id = app.Id,
AlreadyInClinic = app.AlreadyInClinic,
AppointmentType = app.AppointmentType,
BranchId = app.BranchId,
ClientId = app.ClientId,
ClientName = client.Name,
ClientNotified = app.ClientNotified,
Start = app.StartDate,
End = app.EndDate,
HasPayments = cash.Amount != null,
HasProcedures = proc.ClientAppointmentResultId != null,
InsuredAccidentType = app.InsuredAccidentType,
Ordinality = app.Ordinality,
Reason = app.Reason,
SpecialistId = app.SpecialistId,
SpecialistName = spec.Name
}).Where(app => DateValue.Date == app.Start.Value.Date),
})
.AsNoTracking()
.ToListAsync();
}
此查询转换为 SQL:
SELECT [c].[id],
[c].[name],
[c].[number],
[t].[id],
[c1].[id],
[s].[id],
[t0].[id],
[t0].[already_in_clinic],
[t0].[appointment_type],
[t0].[branch_id],
[t0].[client_id],
[t0].[name],
[t0].[client_notified],
[t0].[start_date],
[t0].[end_date],
[t0].[c],
[t0].[c0],
[t0].[insured_accident_type],
[t0].[ordinality],
[t0].[reason],
[t0].[specialist_id],
[t0].[name0],
[t0].[id0]
FROM [clinic_rooms] AS [c]
INNER JOIN (SELECT [c0].[id],
[c0].[already_in_clinic],
[c0].[app_target_id],
[c0].[appointment_date_changed],
[c0].[appointment_files],
[c0].[appointment_source],
[c0].[appointment_type],
[c0].[barcode],
[c0].[branch_id],
[c0].[call],
[c0].[cancel_date],
[c0].[cancel_reason],
[c0].[cancel_type_person],
[c0].[card_number],
[c0].[client_id],
[c0].[client_notified],
[c0].[clinic_room_id],
[c0].[color],
[c0].[create_account_id],
[c0].[create_date],
[c0].[end_date],
[c0].[followup_visit_id],
[c0].[how_did_you_know_id],
[c0].[insurance_company_discount],
[c0].[insurance_guarantor],
[c0].[insurance_policy_id],
[c0].[insurance_specialist],
[c0].[insurance_specialist_phone],
[c0].[insured_accident_type],
[c0].[is_cash_printed],
[c0].[is_synevo_added],
[c0].[is_synevo_checked],
[c0].[is_synevo_validated],
[c0].[ordinality],
[c0].[possible_app_date],
[c0].[priority],
[c0].[reason],
[c0].[show_on_additional_spesialist_dashboard],
[c0].[small_notes],
[c0].[sms_sent],
[c0].[specialist_id],
[c0].[specialist_notified],
[c0].[specialist_recommendation_id],
[c0].[start_date],
[c0].[status],
[c0].[update_account_id],
[c0].[update_date],
[c0].[vendor_order_id],
[c0].[vendor_order_response_json],
[c0].[vendor_order_status],
[c0].[zoom_meeting_url]
FROM [client_appointments] AS [c0]
WHERE ( Cast('2020-08-03' AS DATETIME) =
CONVERT(DATE, [c0].[start_date]) )
AND [c0].[client_id] IS NOT NULL) AS [t]
ON [c].[id] = [t].[clinic_room_id]
INNER JOIN [clients] AS [c1]
ON [t].[client_id] = [c1].[id]
INNER JOIN [specialists] AS [s]
ON [t].[specialist_id] = [s].[id]
LEFT JOIN [client_cash_income] AS [c2]
ON [t].[id] = [c2].[client_appointment_id]
LEFT JOIN [client_appointment_result_procedures] AS [c3]
ON [t].[id] = [c3].[client_appointment_result_id]
OUTER apply (SELECT [t].[id],
[t].[already_in_clinic],
[t].[appointment_type],
[t].[branch_id],
[t].[client_id],
[c1].[name],
[t].[client_notified],
[t].[start_date],
[t].[end_date],
CASE
WHEN [c2].[amount] IS NOT NULL THEN Cast(1 AS BIT)
ELSE Cast(0 AS BIT)
END AS [c],
CASE
WHEN [c3].[client_appointment_result_id] IS NOT
NULL THEN
Cast(1 AS BIT)
ELSE Cast(0 AS BIT)
END AS [c0],
[t].[insured_accident_type],
[t].[ordinality],
[t].[reason],
[t].[specialist_id],
[s].[name] AS [name0],
[c4].[id] AS [id0]
FROM [client_appointments] AS [c4]
WHERE ( Cast('2020-08-03' AS DATETIME) =
CONVERT(DATE, [t].[start_date]) )
AND ( [c].[id] = [c4].[clinic_room_id] )) AS [t0]
ORDER BY [c].[id],
[t].[id],
[c1].[id],
[s].[id],
[t0].[id0]
除了最后一个 WHERE
子句外,这几乎就是我想要的。它将日期与 [t].[start_date]
列进行比较,在我的情况下,它会导致数据重复( OUTER APPLY
适用于 '2020-08-03'
天的记录除外)。
我应该怎么做才能在这个表达式中得到 [c4].[start_date]
?那会给我我想要的结果。
提前致谢!
我看到您正在获取一个房间的所有预约,无论日期如何。请满足以下条件并尝试一次
在您的 linq 中修改以下逻辑
RoomAppointments = room.Appointments.Select(s =>
至
RoomAppointments = room.Appointments.where(y => y.StartDate.Value.Date == DateValue.Date).Select(s =>
不确定约会中 Start_Date 的 属性 名称是否正确,请在更新代码之前更正。