123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- using Dapper;
- using EVCB_OCPP.WEBAPI.Models.WebAPI;
- using EVCB_OCPP.WEBAPI.Models.WebAPI.Dto;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.DependencyInjection;
- using System;
- using System.Collections.Generic;
- using System.Configuration;
- using System.Data;
- using System.Linq;
- using Microsoft.Data.SqlClient;
- using EVCB_OCPP.WEBAPI.Helpers;
- using System.Threading.Tasks;
- using System.Diagnostics;
- using Microsoft.Extensions.Logging;
- using System.Threading;
- using static System.Collections.Specialized.BitVector32;
- using EVCB_OCPP.WEBAPI.Models.Db;
- namespace EVCB_OCPP.WEBAPI.Services
- {
- public interface IChargingStationService
- {
- List<Station> GetStationsbyCustomerId(string customerId);
- List<EVSE> GetEVSEsbyStationId(int stationId, DateTime? dateFrom, DateTime? dateTo, int offset, int limit);
- Task<List<Station>> GetStationsbyCustomerIdAsync(string customerId);
- }
- public class ChargingStationService : IChargingStationService
- {
- //string mainConnectionString;
- //string webConnectionString;
- private readonly IServiceProvider serviceProvider;
- private readonly SqlConnectionFactory<WebDBConetext> webConnectionFactory;
- private readonly ILogger<ChargingStationService> logger;
- public ChargingStationService(
- SqlConnectionFactory<WebDBConetext> webConnectionFactory,
- ILogger<ChargingStationService> logger,
- IServiceProvider serviceProvider)
- {
- //mainConnectionString = configuration.GetConnectionString("MainDBContext");
- //webConnectionString = configuration.GetConnectionString("WebDBContext");
- this.serviceProvider = serviceProvider;
- this.webConnectionFactory = webConnectionFactory;
- this.logger = logger;
- }
- public List<Station> GetStationsbyCustomerId(string customerId)
- {
- return GetStationsbyCustomerIdAsync(customerId).Result;
- }
- public async Task<List<Station>> GetStationsbyCustomerIdAsync(string customerId)
- {
- var watch = Stopwatch.StartNew();
- List<long> times = new();
- List<Station> _stations = new List<Station>();
- var parameters = new DynamicParameters();
- parameters.Add("@CustomerId", customerId, DbType.AnsiString, ParameterDirection.Input, 36);
- using (SqlConnection conn = await webConnectionFactory.CreateAsync())
- {
- string strSql = "Select Id, Name ,Latitude,Longitude,Address from [dbo].[Station] where CustomerId=@CustomerId; ";
- var result = await conn.QueryAsync<Station>(strSql, parameters);
- _stations = result is null ? new List<Station>() : result.ToList();
- }
- times.Add(watch.ElapsedMilliseconds);
- //if (_stations == null)
- //{
- // return _stations;
- //}
- //List<Task> ts = new List<Task>();
- //foreach (var station in _stations)
- //{
- // station.Coordinates = new GetLocation() { Latitude = station.Latitude, Longitude = station.Longitude };
- // ts.Add(Task.Run(async () => { station.EVSEs = await GetEVSEsbyStationIdAsync(station.Id, null, null, -1, 100000); } ));
- //}
- //await Task.WhenAll(ts);
- //await Parallel.ForEachAsync(_stations, async (station, c) => {
- // station.EVSEs = await GetEVSEsbyStationIdAsync(station.Id, null, null, -1, 100000);
- //});
- Dictionary<int, List<string>> stationMachinePair = await GetStationMachinePairAsync(_stations.Select(x => x.Id));
- times.Add(watch.ElapsedMilliseconds);
- foreach (var station in _stations)
- {
- station.Coordinates = new GetLocation() { Latitude = station.Latitude, Longitude = station.Longitude };
- //station.EVSEs = await GetEVSEsbyStationIdAsync(station.Id, null, null, -1, 100000);
- station.EVSEs = stationMachinePair.ContainsKey(station.Id)
- ? await GetEVSEsBytEVSEs(stationMachinePair[station.Id], null, null, -1, 100000)
- : new List<EVSE> { };
- station.EVSEs.ForEach(x => x.StationId = station.Id);
- times.Add(watch.ElapsedMilliseconds);
- }
- watch.Stop();
- if (watch.ElapsedMilliseconds > 1000)
- {
- logger.LogWarning($"GetStationsbyCustomerIdAsync {string.Join("/", times)}");
- }
- return _stations;
- }
- public bool ContainsStation(string customerId, int stationId)
- {
- bool isContains = false;
- var parameters = new DynamicParameters();
- parameters.Add("@CustomerId", customerId, DbType.AnsiString, ParameterDirection.Input, 36);
- parameters.Add("@Id", stationId, DbType.Int32, ParameterDirection.Input);
- using (SqlConnection conn = webConnectionFactory.Create())
- {
- string strSql = "Select count(*) from [dbo].[Station] where CustomerId=@CustomerId and Id=@Id; ";
- isContains = conn.ExecuteScalar<Int32>(strSql, parameters) > 0 ? true : false;
- }
- return isContains;
- }
- public List<EVSE> GetEVSEsbyStationId(int stationId, DateTime? dateFrom, DateTime? dateTo, int offset = -1, int limit = 1000)
- {
- return GetEVSEsbyStationIdAsync(stationId,dateFrom,dateTo,offset,limit).Result;
- }
- public async Task<List<EVSE>> GetEVSEsbyStationIdAsync(int stationId, DateTime? dateFrom, DateTime? dateTo, int offset = -1, int limit = 1000)
- {
- //var watch = Stopwatch.StartNew();
- //List<long> time = new();
- List<EVSE> _chargePoints = new List<EVSE>();
- var parameters = new DynamicParameters();
- parameters.Add("@StationId", stationId, DbType.Int16, ParameterDirection.Input);
- List<string> machineIds = new List<string>();
- using (SqlConnection conn = await webConnectionFactory.CreateAsync())
- {
- string strSql = "Select MachineId from [dbo].[StationMachine] where StationId=@StationId; ";
- machineIds = (await conn.QueryAsync<String>(strSql, parameters)).ToList();
- }
- //time.Add(watch.ElapsedMilliseconds);
- var result = await GetEVSEsBytEVSEs(machineIds, dateFrom, dateTo, offset, limit);
- result.ForEach(x => x.StationId = stationId);
- return result;
- }
- public Task<List<EVSE>> GetEVSEsBytEVSEs(List<string> machineIds, DateTime? dateFrom, DateTime? dateTo, int offset = -1, int limit = 1000)
- {
- return GetEVSEsBytEVSEsWithDapper(machineIds, dateFrom, dateTo, offset, limit);
- //return GetEVSEsBytEVSEsWithSP(machineIds, dateFrom, dateTo, offset, limit);
- }
- public async Task<List<EVSE>> GetEVSEsBytEVSEsWithSP(List<string> machineIds, DateTime? dateFrom, DateTime? dateTo, int offset = -1, int limit = 1000)
- {
- var watch = Stopwatch.StartNew();
- List<EVSE> _chargePoints = new List<EVSE>();
- ChargePointService _CPService = serviceProvider.GetRequiredService<ChargePointService>();// new ChargePointService();
- int startIndex = offset == -1 ? 0 : offset;
- limit += startIndex;
- while (startIndex < limit && startIndex < machineIds.Count)
- {
- var _machineUpdateOn = await _CPService.GetLastUpdatedTimebyMachineIdAsync(machineIds[startIndex]);
- //time.Add(watch.ElapsedMilliseconds);
- if (dateFrom.HasValue && _machineUpdateOn < dateFrom.Value.ToUniversalTime())
- {
- limit++;
- startIndex++;
- continue;
- }
- if (dateFrom.HasValue && dateTo.HasValue && (_machineUpdateOn < dateFrom.Value.ToUniversalTime() || _machineUpdateOn > dateTo.Value.ToUniversalTime()))
- {
- limit++;
- startIndex++;
- continue;
- }
- var _machine = await _CPService.GetBasicInfobyIdAsync(machineIds[startIndex]);
- //time.Add(watch.ElapsedMilliseconds);
- if (_machine != null)
- {
- _machine.LastUpdated = _machineUpdateOn;
- //_machine.StationId = stationId;
- _chargePoints.Add(_machine);
- }
- else
- {
- limit++;
- }
- startIndex++;
- }
- watch.Stop();
- if (watch.ElapsedMilliseconds > 1000)
- {
- logger.LogWarning($"GetEVSEsBytEVSEs {watch.ElapsedMilliseconds}");
- }
- return _chargePoints;
- }
- public async Task<List<EVSE>> GetEVSEsBytEVSEsWithDapper(List<string> machineIds, DateTime? dateFrom, DateTime? dateTo, int offset = -1, int limit = 1000)
- {
- var watch = Stopwatch.StartNew();
- List<long> times = new();
- List<EVSE> _chargePoints = new List<EVSE>();
- ChargePointService _CPService = serviceProvider.GetRequiredService<ChargePointService>();// new ChargePointService();
- int quota = limit;
- int startIndex = offset == -1 ? 0 : offset;
- limit += startIndex;
- var machineIdChunks = machineIds.Chunk(100);
- foreach(var machineIdChunk in machineIdChunks)
- {
- Dictionary<string, DateTime> _machineUpdateOnPairs = await _CPService.GetLastUpdatedTimebyMachineIdAsync(machineIdChunk);
- times.Add(watch.ElapsedMilliseconds);
- _machineUpdateOnPairs = _machineUpdateOnPairs
- .Where(x => !dateFrom.HasValue || x.Value > dateFrom.Value.ToUniversalTime())
- .Where(x => !dateTo.HasValue || x.Value < dateTo.Value.ToUniversalTime())
- .ToDictionary(x=>x.Key,x=>x.Value);
- Dictionary<string, EVSE> pairs = await _CPService.GetBasicInfobyIdAsync(_machineUpdateOnPairs.Select(x=> x.Key));
- times.Add(watch.ElapsedMilliseconds);
- foreach (var pair in pairs)
- {
- var machine = pair.Value;
- machine.LastUpdated = _machineUpdateOnPairs[pair.Key];
- _chargePoints.Add(machine);
- if (_chargePoints.Count > quota)
- break;
- }
-
- //foreach (var pair in _machineUpdateOnPairs)
- //{
- // var _machine = await _CPService.GetBasicInfobyIdAsync(pair.Key);
- // if (_machine != null)
- // {
- // _machine.LastUpdated = pair.Value;
- // //_machine.StationId = stationId;
- // _chargePoints.Add(_machine);
- // }
- // if (_chargePoints.Count > quota)
- // break;
- //}
- if (_chargePoints.Count > quota)
- break;
- }
- watch.Stop();
- if (watch.ElapsedMilliseconds > 1000)
- {
- logger.LogWarning($"GetEVSEsBytEVSEs {string.Join("/", times)}");
- }
- return _chargePoints;
- while (startIndex < limit && startIndex < machineIds.Count)
- {
- DateTime _machineUpdateOn = await _CPService.GetLastUpdatedTimebyMachineIdAsync(machineIds[startIndex]);
- //time.Add(watch.ElapsedMilliseconds);
- if (dateFrom.HasValue && _machineUpdateOn < dateFrom.Value.ToUniversalTime())
- {
- limit++;
- startIndex++;
- continue;
- }
- if (dateFrom.HasValue && dateTo.HasValue && (_machineUpdateOn < dateFrom.Value.ToUniversalTime() || _machineUpdateOn > dateTo.Value.ToUniversalTime()))
- {
- limit++;
- startIndex++;
- continue;
- }
- var _machine = await _CPService.GetBasicInfobyIdAsync(machineIds[startIndex]);
- //time.Add(watch.ElapsedMilliseconds);
- if (_machine != null)
- {
- _machine.LastUpdated = _machineUpdateOn;
- //_machine.StationId = stationId;
- _chargePoints.Add(_machine);
- }
- else
- {
- limit++;
- }
- startIndex++;
- }
- watch.Stop();
- if (watch.ElapsedMilliseconds > 1000)
- {
- logger.LogWarning($"GetEVSEsBytEVSEs {watch.ElapsedMilliseconds}");
- }
- return _chargePoints;
- }
- public async Task<Dictionary<int, List<string>>> GetStationMachinePairAsync(IEnumerable<int> stationIds)
- {
- var parameters = new DynamicParameters();
- parameters.Add("@StationIds", stationIds);
- string strSql = "SELECT StationId, MachineId FROM [dbo].[StationMachine] WHERE StationId IN @StationIds; ";
- using SqlConnection conn = await webConnectionFactory.CreateAsync();
- var result = await conn.QueryAsync<StationMachineDto>(strSql, parameters);
- return result.GroupBy(x => x.StationId).ToDictionary(x => x.Key, x => x.Select(x => x.MachineId).ToList());
- }
- }
- }
|