|
@@ -1,4 +1,5 @@
|
|
-using EVCB_OCPP.Domain;
|
|
|
|
|
|
+using Dapper;
|
|
|
|
+using EVCB_OCPP.Domain;
|
|
using EVCB_OCPP.Packet.Messages.SubTypes;
|
|
using EVCB_OCPP.Packet.Messages.SubTypes;
|
|
using EVCB_OCPP.WSServer.Helper;
|
|
using EVCB_OCPP.WSServer.Helper;
|
|
using Microsoft.Data.SqlClient;
|
|
using Microsoft.Data.SqlClient;
|
|
@@ -21,6 +22,7 @@ public class MeterValueDbService
|
|
{
|
|
{
|
|
private readonly IDbContextFactory<MeterValueDBContext> meterValueDbContextFactory;
|
|
private readonly IDbContextFactory<MeterValueDBContext> meterValueDbContextFactory;
|
|
private readonly ILoggerFactory loggerFactory;
|
|
private readonly ILoggerFactory loggerFactory;
|
|
|
|
+ private readonly MeterValueGroupSingleHandler meterValueGroupSingleHandler;
|
|
private readonly QueueSemaphore insertSemaphore;
|
|
private readonly QueueSemaphore insertSemaphore;
|
|
private readonly string meterValueConnectionString;
|
|
private readonly string meterValueConnectionString;
|
|
private readonly ILogger logger;
|
|
private readonly ILogger logger;
|
|
@@ -31,10 +33,13 @@ public class MeterValueDbService
|
|
IDbContextFactory<MeterValueDBContext> meterValueDbContextFactory,
|
|
IDbContextFactory<MeterValueDBContext> meterValueDbContextFactory,
|
|
ILogger<MeterValueDbService> logger,
|
|
ILogger<MeterValueDbService> logger,
|
|
ILoggerFactory loggerFactory,
|
|
ILoggerFactory loggerFactory,
|
|
- IConfiguration configuration)
|
|
|
|
|
|
+ IConfiguration configuration
|
|
|
|
+ //, MeterValueGroupSingleHandler meterValueGroupSingleHandler
|
|
|
|
+ )
|
|
{
|
|
{
|
|
this.meterValueDbContextFactory = meterValueDbContextFactory;
|
|
this.meterValueDbContextFactory = meterValueDbContextFactory;
|
|
this.loggerFactory = loggerFactory;
|
|
this.loggerFactory = loggerFactory;
|
|
|
|
+ //this.meterValueGroupSingleHandler = meterValueGroupSingleHandler;
|
|
this.meterValueConnectionString = configuration.GetConnectionString("MeterValueDBContext");
|
|
this.meterValueConnectionString = configuration.GetConnectionString("MeterValueDBContext");
|
|
this.logger = logger;
|
|
this.logger = logger;
|
|
|
|
|
|
@@ -73,6 +78,8 @@ public class MeterValueDbService
|
|
//await db.Database.ExecuteSqlRawAsync(sp, parameter.ToArray());
|
|
//await db.Database.ExecuteSqlRawAsync(sp, parameter.ToArray());
|
|
|
|
|
|
return insertMeterValueHandler.HandleAsync(param);
|
|
return insertMeterValueHandler.HandleAsync(param);
|
|
|
|
+ //return InsertWithDapper(param);
|
|
|
|
+ //return meterValueGroupSingleHandler.HandleAsync(param);
|
|
}
|
|
}
|
|
|
|
|
|
private void InitInsertMeterValueHandler()
|
|
private void InitInsertMeterValueHandler()
|
|
@@ -83,9 +90,10 @@ public class MeterValueDbService
|
|
}
|
|
}
|
|
|
|
|
|
insertMeterValueHandler = new GroupSingleHandler<InsertMeterValueParam>(
|
|
insertMeterValueHandler = new GroupSingleHandler<InsertMeterValueParam>(
|
|
- BulkInsertWithCache,
|
|
|
|
|
|
+ BundleInsertWithDapper,
|
|
//loggerFactory.CreateLogger("InsertMeterValueHandler")
|
|
//loggerFactory.CreateLogger("InsertMeterValueHandler")
|
|
- logger
|
|
|
|
|
|
+ logger,
|
|
|
|
+ workerCnt:20
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -97,6 +105,123 @@ public class MeterValueDbService
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private async Task InsertWithDapper(InsertMeterValueParam param)
|
|
|
|
+ {
|
|
|
|
+ var watch = Stopwatch.StartNew();
|
|
|
|
+ long t0, t1, t2, t3;
|
|
|
|
+ if (!await GetTableExist(param.createdOn))
|
|
|
|
+ {
|
|
|
|
+ t0 = watch.ElapsedMilliseconds;
|
|
|
|
+ await InsertWithStoredProcedure(param);
|
|
|
|
+ watch.Stop();
|
|
|
|
+ t1 = watch.ElapsedMilliseconds;
|
|
|
|
+ if (t1 > 500)
|
|
|
|
+ {
|
|
|
|
+ logger.LogWarning("MeterValue InsertWithStoredProcedure {0}/{1}", t0, t1);
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ t0 = watch.ElapsedMilliseconds;
|
|
|
|
+ var tableName = GetTableName(param.createdOn);
|
|
|
|
+ string command = $"""
|
|
|
|
+ INSERT INTO {tableName} (ConnectorId, Value, CreatedOn, ContextId, FormatId, MeasurandId, PhaseId, LocationId, UnitId, ChargeBoxId, TransactionId)
|
|
|
|
+ VALUES (@ConnectorId, @Value, @CreatedOn, @ContextId, @FormatId, @MeasurandId, @PhaseId, @LocationId, @UnitId, @ChargeBoxId, @TransactionId);
|
|
|
|
+ """;
|
|
|
|
+
|
|
|
|
+ var parameters = new DynamicParameters();
|
|
|
|
+ parameters.Add("ConnectorId", param.connectorId, DbType.Int16);
|
|
|
|
+ parameters.Add("Value", param.value, DbType.Decimal, precision: 18, scale: 8);
|
|
|
|
+ parameters.Add("CreatedOn", param.createdOn, DbType.DateTime);
|
|
|
|
+ parameters.Add("ContextId", param.contextId, DbType.Int32);
|
|
|
|
+ parameters.Add("FormatId", param.formatId, DbType.Int32);
|
|
|
|
+ parameters.Add("MeasurandId", param.measurandId, DbType.Int32);
|
|
|
|
+ parameters.Add("PhaseId", param.phaseId, DbType.Int32);
|
|
|
|
+ parameters.Add("LocationId", param.locationId, DbType.Int32);
|
|
|
|
+ parameters.Add("UnitId", param.unitId, DbType.Int32);
|
|
|
|
+ parameters.Add("ChargeBoxId", param.chargeBoxId, DbType.String, size: 50);
|
|
|
|
+ parameters.Add("TransactionId", param.transactionId, DbType.Int32);
|
|
|
|
+
|
|
|
|
+ t1 = watch.ElapsedMilliseconds;
|
|
|
|
+ using var sqlConnection = new SqlConnection(meterValueConnectionString);
|
|
|
|
+ t2 = watch.ElapsedMilliseconds;
|
|
|
|
+ await sqlConnection.ExecuteAsync(command, parameters);
|
|
|
|
+
|
|
|
|
+ watch.Stop();
|
|
|
|
+ t3 = watch.ElapsedMilliseconds;
|
|
|
|
+ if(t3 > 700)
|
|
|
|
+ {
|
|
|
|
+ logger.LogWarning("MeterValue Dapper {0}/{1}/{2}/{3}", t0, t1, t2, t3);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private async Task BundleInsertWithDapper(IEnumerable<InsertMeterValueParam> parms)
|
|
|
|
+ {
|
|
|
|
+ var watch = Stopwatch.StartNew();
|
|
|
|
+ long t0, t1, t2, t3;
|
|
|
|
+
|
|
|
|
+ var parmsList = parms.ToList();
|
|
|
|
+ t0 = watch.ElapsedMilliseconds;
|
|
|
|
+ foreach (var param in parms)
|
|
|
|
+ {
|
|
|
|
+ if (!await GetTableExist(param.createdOn))
|
|
|
|
+ {
|
|
|
|
+ await InsertWithStoredProcedure(param);
|
|
|
|
+ parmsList.Remove(param);
|
|
|
|
+ }
|
|
|
|
+ t1 = watch.ElapsedMilliseconds;
|
|
|
|
+ watch.Stop();
|
|
|
|
+ if (t1 > 500)
|
|
|
|
+ {
|
|
|
|
+ logger.LogWarning("MeterValue InsertWithStoredProcedure {0}/{1}", t0, t1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ t1 = watch.ElapsedMilliseconds;
|
|
|
|
+ //logger.LogInformation("MeterValue bundle insert cnt {0}", parmsList.Count);
|
|
|
|
+ var gruopParams = parmsList.GroupBy(x => GetTableName(x.createdOn));
|
|
|
|
+
|
|
|
|
+ t2 = watch.ElapsedMilliseconds;
|
|
|
|
+ using SqlConnection sqlConnection = new SqlConnection(meterValueConnectionString);
|
|
|
|
+ sqlConnection.Open();
|
|
|
|
+ using var tans = sqlConnection.BeginTransaction();
|
|
|
|
+
|
|
|
|
+ foreach (var group in gruopParams)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ var tableName = group.Key;
|
|
|
|
+ string command = $"""
|
|
|
|
+ INSERT INTO {tableName} (ConnectorId, Value, CreatedOn, ContextId, FormatId, MeasurandId, PhaseId, LocationId, UnitId, ChargeBoxId, TransactionId)
|
|
|
|
+ VALUES (@ConnectorId, @Value, @CreatedOn, @ContextId, @FormatId, @MeasurandId, @PhaseId, @LocationId, @UnitId, @ChargeBoxId, @TransactionId);
|
|
|
|
+ """;
|
|
|
|
+ foreach(var param in group)
|
|
|
|
+ {
|
|
|
|
+ var parameters = new DynamicParameters();
|
|
|
|
+ parameters.Add("ConnectorId", param.connectorId, DbType.Int16);
|
|
|
|
+ parameters.Add("Value", param.value, DbType.Decimal,precision:18, scale:8);
|
|
|
|
+ parameters.Add("CreatedOn", param.createdOn, DbType.DateTime);
|
|
|
|
+ parameters.Add("ContextId", param.contextId, DbType.Int32);
|
|
|
|
+ parameters.Add("FormatId", param.formatId, DbType.Int32);
|
|
|
|
+ parameters.Add("MeasurandId", param.measurandId, DbType.Int32);
|
|
|
|
+ parameters.Add("PhaseId", param.phaseId, DbType.Int32);
|
|
|
|
+ parameters.Add("LocationId", param.locationId, DbType.Int32);
|
|
|
|
+ parameters.Add("UnitId", param.unitId, DbType.Int32);
|
|
|
|
+ parameters.Add("ChargeBoxId", param.chargeBoxId, DbType.String, size:50);
|
|
|
|
+ parameters.Add("TransactionId", param.transactionId, DbType.Int32);
|
|
|
|
+ sqlConnection.Execute(command, parameters, tans);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ tans.Commit();
|
|
|
|
+
|
|
|
|
+ watch.Stop();
|
|
|
|
+ t3 = watch.ElapsedMilliseconds;
|
|
|
|
+ if (t3 > 300)
|
|
|
|
+ {
|
|
|
|
+ logger.LogWarning("MeterValue Dapper {0}/{1}/{2}/{3}", t0, t1, t2, t3);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
private async Task BulkInsertWithCache(IEnumerable<InsertMeterValueParam> parms)
|
|
private async Task BulkInsertWithCache(IEnumerable<InsertMeterValueParam> parms)
|
|
{
|
|
{
|
|
var watcher = Stopwatch.StartNew();
|
|
var watcher = Stopwatch.StartNew();
|