Advertisement
Guest User

Untitled

a guest
Mar 30th, 2020
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.36 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.SqlClient;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Xml.Linq;
  8. using Waypoint.Models;
  9. using Waypoint.Models.Queries;
  10. using Dapper;
  11. using Dapper.Contrib;
  12. using System.Data;
  13. using Waypoint.Models.Contracts;
  14.  
  15. namespace Waypoint.DAL
  16. {
  17. public class TrackingQueryHandler : IQueryHandler<TrackingQuery, List<TrackingQueryResult>>, IQueryHandler<TrackingCountQuery, int>
  18. {
  19. public string ConnectionString { get; set; }
  20.  
  21. public TrackingQueryHandler()
  22. {
  23. }
  24. public TrackingQueryHandler(string connectionString)
  25. {
  26. ConnectionString = connectionString;
  27. }
  28. public async Task<List<TrackingQueryResult>> Handle(TrackingQuery query)
  29. {
  30. using (var sqlConnection = new SqlConnection(ConnectionString))
  31. {
  32. sqlConnection.Open();
  33.  
  34. var vehicleGroupIds = GetUserVehicleGroupId(query, sqlConnection);
  35. var sqlTemplate = await BuildSql(query, vehicleGroupIds, false);
  36.  
  37. var map = new Dictionary<string, TrackingQueryResult>();
  38. var map_t = new Dictionary<string, TrackingData>();
  39.  
  40. var list = await sqlConnection.QueryAsync<TrackingQueryResult, TrackingData, TrackingAlert, TrackingQueryResult>
  41. (sqlTemplate.Sql, (v, t, a) =>
  42. {
  43. TrackingQueryResult vehicle;
  44. var key = $"id:{v.VehicleId}";
  45. var key_t = $"id:{v.VehicleId}_cid:{t.CrumbId}";
  46.  
  47. if (!map.TryGetValue(key, out vehicle))
  48. {
  49. map[key] = vehicle = v;
  50. }
  51. if (t != null) //left join
  52. {
  53. TrackingData crumb;
  54. if (!map_t.TryGetValue(key_t, out crumb))
  55. {
  56. map_t[key_t] = crumb = t;
  57. vehicle.TrackingItems.Add(t);
  58. }
  59.  
  60. if (a != null)
  61. {
  62. crumb.TrackingAlerts.Add(a);
  63. }
  64. }
  65. return vehicle;
  66. }, sqlTemplate.Template.Parameters, splitOn: "CrumbId,AlertId")
  67. .ContinueWith(t => t.Result.ToList());
  68.  
  69. var trackingResult = map.Values.ToList();
  70. if (!query.Filter.IsNullOrWhiteSpace())
  71. {
  72. trackingResult = trackingResult
  73. .Where(t => t.VehicleName.Has(query.Filter) || t.PlateNo.Has(query.Filter) || t.IMEI.Has(query.Filter) || t.Phone.Has(query.Filter) || t.ChassisNo.Has(query.Filter))
  74. .ToList();
  75. }
  76.  
  77. return await Task.FromResult(trackingResult);
  78. }
  79. }
  80.  
  81. public async Task<int> Handle(TrackingCountQuery query)
  82. {
  83. using (var sqlConnection = new SqlConnection(ConnectionString))
  84. {
  85. sqlConnection.Open();
  86.  
  87. var vehicleGroupIds = GetUserVehicleGroupId(query, sqlConnection);
  88. var sqlTemplate = await BuildSql(query, vehicleGroupIds, true);
  89.  
  90. var count = await sqlConnection.ExecuteScalarAsync<int>
  91. (sql: sqlTemplate.Sql, param: sqlTemplate.Template.Parameters);
  92.  
  93. return await Task.FromResult(count);
  94. }
  95. }
  96.  
  97. private List<int> GetUserVehicleGroupId(TrackingQuery query, SqlConnection sqlConnection)
  98. {
  99. try
  100. {
  101. if (query.IsAdminUser)
  102. {
  103. return new List<int>();
  104. }
  105. var vehicleGroupIds = sqlConnection
  106. .Query<int>("select VehicleGroupId from UserVehicleGroups where UserId = @UserId", param: new { query.UserId })
  107. .ToList();
  108. return vehicleGroupIds;
  109. }
  110. catch (Exception x)
  111. {
  112. throw;
  113. }
  114. }
  115.  
  116. private async Task<SqlTemplate> BuildSql(TrackingQuery query, List<int> vehicleGroupIds, bool isCount)
  117. {
  118. var builder = new Dapper.SqlBuilder();
  119. var sql = "";
  120. var template = builder.AddTemplate(
  121. @"
  122. /**filtered_vehicles**/
  123.  
  124. select /**select_result**/ from
  125. (
  126. /**select**/
  127. from VehicleStatuses vs WITH (NOLOCK)
  128. /**join**/
  129. join ContractVehicleView v with(nolock) on v.VehicleId = vs.VehicleId and v.TenantId = vs.TenantId
  130. --join Vehicles v with(nolock) on v.VehicleId = vs.VehicleId and v.TenantId = vs.TenantId
  131. --join Devices d with(nolock) on d.VehicleId = v.VehicleId
  132. left join EventTranslation et with(nolock) on et.EventId = vs.EventId
  133. inner join ContractDetails cd with(nolock) on vs.VehicleId = cd.VehicleId and cd.IsActive = 1
  134. /**join_alerts**/
  135. /**where**/
  136. ) t
  137. /**paging**/
  138. /**orderby**/
  139.  
  140. OPTION(RECOMPILE,MAXDOP 1)
  141. "
  142. );
  143. builder.Select(@"SELECT ROW_NUMBER() OVER (ORDER BY v.VehicleId asc, vs.TimeStamp asc) RowNo, DENSE_RANK() OVER (ORDER BY v.VehicleId asc) DenseRowNo,
  144. --v.VehicleId, v.Name VehicleName, v.Make, v.Model, v.PlateNo, d.IMEI, d.Phone,
  145. v.VehicleId, v.VehicleName VehicleName, v.Make, v.Model, v.PlateNo, v.IMEI, v.Phone, v.ChassisNo,
  146. v.StreamingDeviceIMEI, v.StreamingDeviceType,
  147. vs.CrumbId, vs.TimeStamp, Latitude Lat, Longitude Lng, Angle, HDOP, Speed, vs.CreationDate, vs.Temperature, vs.IsEngineOn, vs.BrakingHarsh, vs.BrakingExtreme, vs.AccelerationHarsh,
  148. ISNULL(et.EventId, 0) EventId, ISNULL(et.Name, '') EventName");
  149.  
  150. builder.Where("vs.TenantId = @tenantId", new { tenantId = query.TenantId });
  151. //builder.Where("vs.TimeStamp ")
  152. // builder.InnerJoin("ContractDetails cd on c.VehicleId = cd.VehicleId && cd.IsActive = true");
  153.  
  154. if (query.VehicleState == VehicleState.Active)
  155. {
  156. var from = DateTime.UtcNow.AddHours(-1);
  157. builder.Where("vs.TimeStamp >= @from", new { from = from });
  158. }
  159. else if (query.OnlyLastLocation)
  160. {
  161. builder.Where("vs.TimeStamp >= @from", new { from = DateTime.UtcNow.Subtract(query.Time) });
  162. }
  163. else
  164. {
  165. builder.Where("vs.TimeStamp >= @from", new { from = DateTime.UtcNow.Subtract(query.Time) });
  166. }
  167.  
  168. if (query.VehicleId > 0)
  169. {
  170. builder.Where("v.VehicleId = @vehicleId", new { vehicleId = query.VehicleId });
  171. }
  172.  
  173. if (vehicleGroupIds.Count > 0)
  174. {
  175. builder.Where(@"(exists (
  176. select * from
  177. Vehicles vv with(nolock) join
  178. VehicleItems vi with(nolock) on vv.VehicleId = vi.VehicleId join
  179. VehicleGroups vg with(nolock) on vi.VehicleGroupId = vg.VehicleGroupId
  180. where vg.VehicleGroupId in @VehicleGroupIds and v.VehicleId = vv.VehicleId))", new { VehicleGroupIds = vehicleGroupIds });
  181. }
  182.  
  183. if (query.IncludeAlerts)
  184. {
  185. builder.Select(@"tac.AlertId, a.Name, ISNULL(a.Description, '') AlertDescription, a.Priority, ta.FirstTime, ta.LastTime");
  186.  
  187. builder.AddClause("join_alerts",
  188. @"left join TriggeredAlertCrumbs tac with(nolock) on tac.CrumbId = vs.CrumbId
  189. left join TriggeredAlerts ta with(nolock) on tac.TriggeredAlertId = ta.TriggeredAlertId
  190. left join Alerts a with(nolock) on tac.AlertId = a.AlertId and a.IsReported = 1");
  191.  
  192. //builder.Where("(a.IsReported is NULL OR a.IsReported = 1)");
  193. }
  194.  
  195. if (!isCount)
  196. {
  197. builder.AddClause("select_result", "*");
  198. builder.OrderBy("DenseRowNo asc, RowNo asc");
  199. if (query.IsPaged)
  200. {
  201. _IncludePaging(query, builder);
  202. }
  203. }
  204. else
  205. {
  206. builder.AddClause("select_result", "count(*)");
  207. }
  208.  
  209. sql = template.ResolveSql();
  210. return new SqlTemplate
  211. {
  212. Sql = sql,
  213. Template = template
  214. };
  215. }
  216.  
  217. private void _IncludePaging(TrackingQuery query, SqlBuilder builder)
  218. {
  219. var page = query.Page >= 1 ? query.Page : 1;
  220. builder.AddClause("paging",
  221. @"WHERE RowNo >= ((@page-1)*@pagesize)+1 AND RowNo <= ((@page)*@pagesize)",
  222. new { page = page, pagesize = query.PageSize });
  223. }
  224.  
  225.  
  226. private async Task _FilterByVehicles(VehicleFilters filters, SqlBuilder builder)
  227. {
  228. var filterBuilder = new Dapper.SqlBuilder();
  229. var filterTemplate = filterBuilder.AddTemplate(
  230. @"
  231. declare @tbl_vehicle_ids table(Id int);
  232.  
  233. insert into @tbl_vehicle_ids(Id)
  234. select ref.value('.[1]', 'int')
  235. from @vehicle_ids.nodes('List/Item') n(ref);"
  236. );
  237.  
  238. var filteredVehiclesXml = await FilteredoXml(filters.FilteredVehicleIds);
  239. filterBuilder.AddParameter("vehicle_ids", filteredVehiclesXml, DbType.Xml);
  240.  
  241. builder.AddClause("filtered_vehicles", filterTemplate.ResolveSql(), filterTemplate.Parameters);
  242. builder.Where("exists (select * from @tbl_vehicle_ids where Id = v.VehicleId)");
  243. }
  244.  
  245.  
  246. private void _IncludePaging(VehicleQuery query, SqlBuilder builder)
  247. {
  248. builder.AddClause("paging",
  249. @"WHERE DenseRowNo >= ((@page-1)*@pagesize)+1 AND DenseRowNo <= ((@page)*@pagesize)",
  250. new { page = query.Page, pagesize = query.PageSize });
  251. }
  252.  
  253. public async Task<List<int>> FilterVehicles(SqlConnection connection, VehicleQuery query)
  254.  
  255. {
  256. var builder = new Dapper.SqlBuilder();
  257.  
  258. var waypointBuilder = new Dapper.SqlBuilder();
  259. var waypointTemplate = waypointBuilder.AddTemplate(
  260. @"select v.VehicleId
  261. from Vehicles v with(nolock) join
  262. Devices d with(nolock) on v.VehicleId = d.VehicleId
  263. where v.TenantId = @tenantId
  264. and (v.Name like @filter or v.PlateNo = @filter or d.IMEI = @filter or d.Phone = @filter)
  265. and exists(select * from RfidItems where VehicleId = v.VehicleId and TenantId = v.TenantId and ScannedOn >= @from and ScannedOn < @to)"
  266. );
  267.  
  268. waypointBuilder.AddParameters(new
  269. {
  270. tenantId = query.TennantId,
  271. filter = query.VehiclesFilter.SqlLike(),
  272. from = query.From,
  273. to = query.To
  274. });
  275.  
  276. var vehicleHistory = await connection.QueryAsync<int>(waypointTemplate.ResolveSql(), waypointTemplate.Parameters)
  277. .ContinueWith(t => t.Result.ToList());
  278.  
  279. return await Task.FromResult(vehicleHistory);
  280. }
  281.  
  282.  
  283. public async Task<string> FilteredoXml<T>(List<T> list)
  284. {
  285. var xml = new XElement("List", list.Select(x =>
  286. new XElement("Item", x.ToString()))
  287. );
  288. var result = xml.ToString();
  289. return await Task.FromResult(result);
  290. }
  291. }
  292. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement