如何更改 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 的 属性 名称是否正确,请在更新代码之前更正。