我正在使用具有相同参数的相同 SQL 查询将 Visual Basic API 转换为 .NET 8,并且我注意到有一个特定行未显示在响应对象中。
查询使用 UNION ALL 并且该行仅存在于第二个 SELECT 语句中:
SELECT
A.Appointment_Id,
A.Appointment_Date,
-- other columns
FROM Appointments A (NOLOCK)
LEFT JOIN Some_Table ST (NOLOCK) ST.Id = A.Appointment_Id
-- more tables using LEFT JOIN
WHERE A.Appointment_Date BETWEEN '07/01/2024 00:00:00' AND '07/31/2024 23:59:59'
UNION ALL
SELECT
DA.Appointment_Id,
DA.Appointment_Date,
-- other columns
FROM Deleted_Appointments DA (NOLOCK)
LEFT JOIN Some_Table ST (NOLOCK) ST.Id = DA.Appointment_Id
-- more tables using LEFT JOIN
WHERE DA.Appointment_Date BETWEEN '07/01/2024 00:00:00' AND '07/31/2024 23:59:59'
使用 Dapper 的 QueryAsync 检索数据的 C# 代码:
public async Task<List<AppointmentsResponse>> GetAppointments(/* parameters */)
{
// my SQL query
using var con = connectionFactory.CreateConnection();
var result = await con.QueryAsync<AppointmentsResponse>(sql.ToString());
return result.ToList();
}
我尝试使用
foreach
循环遍历每一行并检查它们是否正确返回,并且丢失的行被完全跳过。我也尝试过使用 QueryMultipleAsync 但结果保持不变。
我将相同的查询与 Visual Basic API 中的查询进行了比较,它们都按在 Microsoft SSMS 中执行时应有的方式显示该查询。
VB 实现也正确返回它。
不会完全解决问题,所以只是社区维基,但我会像这样编写 SQL:
SELECT
A.Appointment_Id,
A.Appointment_Date,
-- other columns
FROM Appointments A
LEFT JOIN Some_Table ST ON ST.Id = A.Appointment_Id
-- more tables using LEFT JOIN
WHERE A.Appointment_Date >= '20240701 00:00:00' AND A.Appointment_Date < '20240801 00:00:00'
UNION ALL
SELECT
DA.Appointment_Id,
DA.Appointment_Date,
-- other columns
FROM Deleted_Appointments DA (NOLOCK)
LEFT JOIN Some_Table ST ON ST.Id = DA.Appointment_Id
-- more tables using LEFT JOIN
WHERE DA.Appointment_Date >= '20240701 00:00:00' AND DA.Appointment_Date < '20240801 00:00:00'
在连接之前在子查询或CTE中的Appointments和Deleted_Appointments表上进行联合(和日期过滤器)可能会更诱人,但是如果不知道索引和查询其余部分的内容,就很难知道如果这有帮助的话。