У меня есть таблица с данными о местоположении (Lat / Lngs), которые хранятся в виде географического типа.
Теперь эти данные о местоположении представляют собой путешествие, поэтому я хочу рассчитать расстояние, пройденное во время путешествия, расстояние в день и расстояние в месяц. Поэтому для этого мне нужно свойство, чтобы рассчитать расстояние от следующего местоположения в Путешествии.
Если я делаю это, используя выбор из таблицы с оконной функцией, производительность очень хорошая, и план выполнения кажется нормальным. План выполнения
Это запрос -
Select
iVehicleMonitoringId,
iAssetId,
iDriverId,
dtUtcDatetime,
sptGeoLocaitonPoint,
fAngel,
sDirection,
fSpeedKPH,
eEventCode,
fDistanceTravelled = sptGeoLocaitonPoint.STDistance(LEAD(sptGeoLocaitonPoint) OVER(PARTITION BY iAssetId ORDER BY dtUTCDateTime)),
eIgnition,
eDoor,
eSeatbelt,
eIgnition2,
sAddress
From dbo.VehicleMonitoringLog
Where iAssetId = 1
AND dtUTCDateTime BETWEEN N'2017-12-27' AND N'2017-12-27 23:59:59.997'
Теперь, потому что мне нужно это свойство Вычислить Расстояние в моем коде. Я решил создать представление SQL со свойством fDistanceTravelled
.
CREATE VIEW [dbo].[TB5_xPT_VehicleMonitoringLogs]
AS
Select
iVehicleMonitoringId = ISNULL(iVehicleMonitoringId, -1),
iAssetId,
iDriverId,
dtUtcDatetime,
sptGeoLocaitonPoint,
fAngel,
sDirection,
fSpeedKPH,
eEventCode,
fDistanceTravelled = sptGeoLocaitonPoint.STDistance(LEAD(sptGeoLocaitonPoint) OVER(PARTITION BY iAssetId ORDER BY dtUTCDateTime)),
eIgnition,
eDoor,
eSeatbelt,
eIgnition2,
sAddress
From dbo.VehicleMonitoringLog
GO
Но когда я импортирую это представление в Entity Framework, он получает тайм-аут. Поэтому я проверил план выполнения, и он не соответствует выбранному в таблице.
Просмотр плана выполнения
Это запрос -
Select
*
From TB5_xPT_VehicleMonitoringLogs
Where iAssetId = 1
AND dtUTCDateTime BETWEEN N'2017-12-27' AND N'2017-12-27 23:59:59.997'
Чтобы сделать это в коде, мне нужно просмотреть все журналы местоположений в списке.
DbGeography prevPoint = null;
foreach (var historyLog in historyLogs)
{
var distanceFromPrevPoint = 0.0;
if (prevPoint != null)
{
var distance = prevPoint.Distance(historyLog.sptGeoLocaitonPoint);
if (distance != null)
distanceFromPrevPoint = Math.Round(((double)distance * .001), 2);
}
var locationLog = Mapper.Map<LocationLogDTO>(historyLog);
locationLog.DistanceTravelled = distanceFromPrevPoint;
prevPoint = historyLog.sptGeoLocaitonPoint;
historyDto.LocationLogs.Add(locationLog);
}
Я не хочу этого делать. Мне нужен лучший способ сделать это.
EDIT
Изображение Объяснение вычисления столбца fDistanceTravelled
.
![enter image description here](https://i.stack.imgur.com/pF0rO.png)