Итак, я пытаюсь сгенерировать запрос в структуре сущностей, который выбирает только последнюю запись из дочернего элемента дочернего элемента. Я могу сделать это, однако структура сущностей генерирует несколько запросов для достижения этого, что негативно влияет на производительность.
Вот что я придумал:
_entities.Rentals.Include(r => r.CarClass)
.Include(r => r.Car).ThenInclude(x => x.CheckSheets).ThenInclude(y => y.ElectronicCheckSheetVehicleDetail)
.Include(r => r.Hirer)
.Include(r => r.Agent)
.Include(r => r.AdditionalDrivers)
.Include(x => x.Payments)
.Include(r => r.RentalAccessories).ThenInclude(y => y.Accessory)
.Where(....)
).Select(s => new Rental()
{
RentalId = s.RentalId,
// More props
Agent = s.Agent,
Hirer = s.Hirer,
Car = new Car {
// More props from this child
CheckSheets = s.Car.CheckSheets.OrderByDescending(o => o.Id).Take(1).Select(a => new ElectronicCheckSheet() { ElectronicCheckSheetVehicleDetail = a.ElectronicCheckSheetVehicleDetail }).ToList()
},
CarClass = s.CarClass,
AdditionalDrivers = s.AdditionalDrivers,
RentalAccessories = s.RentalAccessories.Select(a => new RentalAccessory() {
// More props from this child
Accessory = a.Accessory
}).ToList(),
Payments = s.Payments,
AssignedDriver = s.AssignedDriver
});
Все работает сниже основной целью было выбрать только последнюю запись из CheckSheets и получить соответствующий ElectronicCheckSheetVehicleDetail.
Но когда я запускаю Profiler, я вижу много запросов, выполняемых для чего-то, что может быть достигнуто с помощью объединений, но я не могу понять, что это правильно.
Сгенерированы следующие запросы:
exec sp_executesql N'SELECT {Column names}
FROM [Rental] AS [r]
INNER JOIN [CarClass] AS [r.CarClass] ON [r].[BookedCarClassId] = [r.CarClass].[CarClassId]
LEFT JOIN [Car] AS [r.Car] ON [r].[BookedCarId] = [r.Car].[CarId]
INNER JOIN [Hirer] AS [r.Hirer] ON [r].[HirerId] = [r.Hirer].[HirerId]
LEFT JOIN [Agent] AS [r.Agent] ON [r].[AgentId] = [r.Agent].[AgentId]
WHERE (([r].[PickupDate] IS NOT NULL AND (CONVERT(date, [r].[PickupDate]) = CONVERT(date, CONVERT(date, GETDATE())))) AND (([r].[Status] = @__GetDescription_0) OR (((([r].[Status] = @__GetDescription_1) AND [r].[IsOnlineCheckinCompleted] IS NOT NULL) AND ([r].[IsOnlineCheckinCompleted] = 1)) AND ([r].[OnlineCheckinMethod] = @__GetDescription_2)))) AND ([r].[PickupPoint] IS NOT NULL AND ([r].[PickupPoint] = @__branchId_Value_3))
ORDER BY [r].[RentalId]',N'@__GetDescription_0 nvarchar(4000),@__GetDescription_1 nvarchar(4000),@__GetDescription_2 nvarchar(4000),@__branchId_Value_3 int',@__GetDescription_0=N'Picked up',@__GetDescription_1=N'Confirmed',@__GetDescription_2=N'App',@__branchId_Value_3=10
exec sp_executesql N'SELECT TOP(1) {Column names}
FROM [ElectronicCheckSheet] AS [o]
LEFT JOIN [ElectronicCheckSheetVehicleDetail] AS [o.ElectronicCheckSheetVehicleDetail] ON [o].[VehicleDetail_Id] = [o.ElectronicCheckSheetVehicleDetail].[Id]
WHERE @_outer_CarId = [o].[Car_CarId]
ORDER BY [o].[Id] DESC',N'@_outer_CarId int',@_outer_CarId=17789
exec sp_executesql N'SELECT {Column names}
FROM [AdditionalDriver] AS [r.AdditionalDrivers]
INNER JOIN (
SELECT [r0].[RentalId]
FROM [Rental] AS [r0]
INNER JOIN [CarClass] AS [r.CarClass0] ON [r0].[BookedCarClassId] = [r.CarClass0].[CarClassId]
LEFT JOIN [Car] AS [r.Car0] ON [r0].[BookedCarId] = [r.Car0].[CarId]
INNER JOIN [Hirer] AS [r.Hirer0] ON [r0].[HirerId] = [r.Hirer0].[HirerId]
LEFT JOIN [Agent] AS [r.Agent0] ON [r0].[AgentId] = [r.Agent0].[AgentId]
WHERE (([r0].[PickupDate] IS NOT NULL AND (CONVERT(date, [r0].[PickupDate]) = CONVERT(date, CONVERT(date, GETDATE())))) AND (([r0].[Status] = @__GetDescription_0) OR (((([r0].[Status] = @__GetDescription_1) AND [r0].[IsOnlineCheckinCompleted] IS NOT NULL) AND ([r0].[IsOnlineCheckinCompleted] = 1)) AND ([r0].[OnlineCheckinMethod] = @__GetDescription_2)))) AND ([r0].[PickupPoint] IS NOT NULL AND ([r0].[PickupPoint] = @__branchId_Value_3))
) AS [t] ON [r.AdditionalDrivers].[RentalId] = [t].[RentalId]
ORDER BY [t].[RentalId]',N'@__GetDescription_0 nvarchar(4000),@__GetDescription_1 nvarchar(4000),@__GetDescription_2 nvarchar(4000),@__branchId_Value_3 int',@__GetDescription_0=N'Picked up',@__GetDescription_1=N'Confirmed',@__GetDescription_2=N'App',@__branchId_Value_3=10
exec sp_executesql N'SELECT {Column names}
FROM [RentalAccessory] AS [r.RentalAccessories]
LEFT JOIN [Accessory] AS [a.Accessory] ON [r.RentalAccessories].[AccessoryId] = [a.Accessory].[AccessoryId]
INNER JOIN (
SELECT [r1].[RentalId]
FROM [Rental] AS [r1]
INNER JOIN [CarClass] AS [r.CarClass1] ON [r1].[BookedCarClassId] = [r.CarClass1].[CarClassId]
LEFT JOIN [Car] AS [r.Car1] ON [r1].[BookedCarId] = [r.Car1].[CarId]
INNER JOIN [Hirer] AS [r.Hirer1] ON [r1].[HirerId] = [r.Hirer1].[HirerId]
LEFT JOIN [Agent] AS [r.Agent1] ON [r1].[AgentId] = [r.Agent1].[AgentId]
WHERE (([r1].[PickupDate] IS NOT NULL AND (CONVERT(date, [r1].[PickupDate]) = CONVERT(date, CONVERT(date, GETDATE())))) AND (([r1].[Status] = @__GetDescription_0) OR (((([r1].[Status] = @__GetDescription_1) AND [r1].[IsOnlineCheckinCompleted] IS NOT NULL) AND ([r1].[IsOnlineCheckinCompleted] = 1)) AND ([r1].[OnlineCheckinMethod] = @__GetDescription_2)))) AND ([r1].[PickupPoint] IS NOT NULL AND ([r1].[PickupPoint] = @__branchId_Value_3))
) AS [t0] ON [r.RentalAccessories].[RentalId] = [t0].[RentalId]
ORDER BY [t0].[RentalId]',N'@__GetDescription_0 nvarchar(4000),@__GetDescription_1 nvarchar(4000),@__GetDescription_2 nvarchar(4000),@__branchId_Value_3 int',@__GetDescription_0=N'Picked up',@__GetDescription_1=N'Confirmed',@__GetDescription_2=N'App',@__branchId_Value_3=10
exec sp_executesql N'SELECT {Column names}
FROM [Payment] AS [r.Payments]
INNER JOIN (
SELECT [r2].[RentalId]
FROM [Rental] AS [r2]
INNER JOIN [CarClass] AS [r.CarClass2] ON [r2].[BookedCarClassId] = [r.CarClass2].[CarClassId]
LEFT JOIN [Car] AS [r.Car2] ON [r2].[BookedCarId] = [r.Car2].[CarId]
INNER JOIN [Hirer] AS [r.Hirer2] ON [r2].[HirerId] = [r.Hirer2].[HirerId]
LEFT JOIN [Agent] AS [r.Agent2] ON [r2].[AgentId] = [r.Agent2].[AgentId]
WHERE (([r2].[PickupDate] IS NOT NULL AND (CONVERT(date, [r2].[PickupDate]) = CONVERT(date, CONVERT(date, GETDATE())))) AND (([r2].[Status] = @__GetDescription_0) OR (((([r2].[Status] = @__GetDescription_1) AND [r2].[IsOnlineCheckinCompleted] IS NOT NULL) AND ([r2].[IsOnlineCheckinCompleted] = 1)) AND ([r2].[OnlineCheckinMethod] = @__GetDescription_2)))) AND ([r2].[PickupPoint] IS NOT NULL AND ([r2].[PickupPoint] = @__branchId_Value_3))
) AS [t1] ON [r.Payments].[RentalId] = [t1].[RentalId]
ORDER BY [t1].[RentalId]',N'@__GetDescription_0 nvarchar(4000),@__GetDescription_1 nvarchar(4000),@__GetDescription_2 nvarchar(4000),@__branchId_Value_3 int',@__GetDescription_0=N'Picked up',@__GetDescription_1=N'Confirmed',@__GetDescription_2=N'App',@__branchId_Value_3=10
Можно ли как-то заставить инфраструктуру сущностей сделать это в одном запросе? Желательно без использования запроса Linq?
ОБНОВЛЕНИЕ:
Я также попытался ограничить результаты в этом разделе запроса без какой-либо удачи, но я не уверен, что это может быть ключом крешение моей проблемы:
.Include(r => r.Car).ThenInclude(x => x.CheckSheets).ThenInclude(y => y.ElectronicCheckSheetVehicleDetail)