多个 Mysql 条目的未知原因
Unknow reason for multiple Mysql Entries
我有一项服务可以检索历史数据并将其保存在 MySQL table
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
//Get Relevant Gateways
string GetRouters = "SELECT * FROM RouterModel;";
var Routers = await dataAccess.LoadData<RouterModel, dynamic>(GetRouters, new { }, _config.GetConnectionString("MainDB"));
string GetMeters = "SELECT * FROM PowerMeterModel;";
var Meters = await dataAccess.LoadData<PowerMeterModel, dynamic>(GetMeters, new { }, _config.GetConnectionString("MainDB"));
foreach (RouterModel Router in Routers)
{
if (Router.IsHavePowerMeters)
{
foreach (PowerMeterModel Meter in Meters.Where(x => x.IdGateway == Router.Id).ToList())
{
if (Meter.IsActive)
{
actionList.Add(new Action(() =>
{
GetHistory(Router, Meter);
_logger.LogInformation("Synced History meter:" + Meter.SerialNumber.ToString());
}));
}
}
}
}
Parallel.Invoke(actionList.ToArray());
actionList.Clear();
_logger.LogWarning("*************** Sync loop is finished ***************");
await Task.Delay(60*1000, stoppingToken);
}
}
public async void GetHistory(RouterModel Router, PowerMeterModel Meter)
{
Web device = new() { IpAddress = Router.IpAddress, UserName = Meter.Username, Password = Meter.Password, Port = Meter.TcpPort };
StringBuilder SqlQuery = new();
StringBuilder TimeString = new();
ElnetMcMapping elnetMcMapping = new();
ElnetMcModel mcReadings = new();
if (Meter.ModelClass == nameof(ElnetMcModel).ToString())
{
for (int day = 1; day < 4; day++)
{
List<List<double>> responeData = new();
DateTime date = todayDate.AddDays(-day);
for (int j = 0; j < elnetMcMapping.DataItems.Count; j += 8)
{
var items = elnetMcMapping.DataItems.Skip(j).Take(8);
device.Items = items.Select(x => x.Address.ToString()).ToList();
var responseString = device.GetElnetReadings(httpClient, 2, date);
if (responseString != null)
{
int check = responeData.Count;
responeData.AddRange(JsonConvert.DeserializeObject<List<List<double>>>(responseString));
}
else { return; }
}
for (int j = 0; j < elnetMcMapping.DataItems.Count; j++) { elnetMcMapping.DataItems[j].Value = responeData[j]; }
foreach (MetaData metaData in elnetMcMapping.DataItems)
{
Type type = mcReadings.GetType();
PropertyInfo prop = type.GetProperty(metaData.Label);
if (prop.PropertyType == typeof(decimal)) { prop.SetValue(mcReadings, Convert.ToDecimal(metaData.Value[0]) * metaData.Multiplier, null); }
else if (prop.PropertyType == typeof(string)) { prop.SetValue(mcReadings, metaData.Value[0].ToString(), null); }
else if (prop.PropertyType == typeof(int)) { prop.SetValue(mcReadings, int.Parse(metaData.Value[0].ToString()), null); }
else if (prop.PropertyType == typeof(DateTime)) { prop.SetValue(mcReadings, DateTime.Now, null); }
else { return; }
}
var propList = mcReadings.GetType().GetProperties().ToList();
SqlQuery.Append("INSERT INTO " + Meter.DataTableName + " (");
foreach (PropertyInfo prop in propList) { SqlQuery.Append(prop.Name + ","); }
SqlQuery.Remove(SqlQuery.Length - 1, 1);
SqlQuery.Append(") VALUES (");
foreach (PropertyInfo prop in propList)
{
if (prop.PropertyType == typeof(DateTime))
{
DateTime dateTime = (DateTime)prop.GetValue(mcReadings);
SqlQuery.Append("'" + dateTime.ToString("yyyy-MM-dd HH:mm:ss") + "'" + ",");
}
else { SqlQuery.Append(prop.GetValue(mcReadings).ToString() + ","); }
}
SqlQuery.Remove(SqlQuery.Length - 1, 1);
SqlQuery.Append(");");
await dataAccess.SaveData(SqlQuery.ToString(), mcReadings, _config.GetConnectionString("PwrMeterDb"));
}
}
}
}
}
上面的代码应该只添加 4 MySql 行,而不是我得到 6,看起来整个方法
每次循环都重新开始 for (int day = 1; day < 4; day++)
改变它的价值。
我得到 6 行而不是 4 行(每天一行)
我得到 10 行而不是 5 行(每天一行)
而不是得到 6 行(每天一行)我得到 15
而不是得到 7 行(每天一行)我得到 21
有什么想法是错误的吗?
您没有在每个循环开始时清除 SqlQuery
StringBuilder
对象。
因此,在第一次迭代中,它有一个 INSERT
查询。在第二次迭代中,它有两个,总共三个 INSERT。在第三次迭代中,它有三个,总共六个。在第四次迭代中,它有四个 INSERT,总共十个。这会产生您正在观察的 1、3、6、10、15、21 序列。
在每个循环开始时调用 SqlQuery.Clear()
。
我有一项服务可以检索历史数据并将其保存在 MySQL table
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
//Get Relevant Gateways
string GetRouters = "SELECT * FROM RouterModel;";
var Routers = await dataAccess.LoadData<RouterModel, dynamic>(GetRouters, new { }, _config.GetConnectionString("MainDB"));
string GetMeters = "SELECT * FROM PowerMeterModel;";
var Meters = await dataAccess.LoadData<PowerMeterModel, dynamic>(GetMeters, new { }, _config.GetConnectionString("MainDB"));
foreach (RouterModel Router in Routers)
{
if (Router.IsHavePowerMeters)
{
foreach (PowerMeterModel Meter in Meters.Where(x => x.IdGateway == Router.Id).ToList())
{
if (Meter.IsActive)
{
actionList.Add(new Action(() =>
{
GetHistory(Router, Meter);
_logger.LogInformation("Synced History meter:" + Meter.SerialNumber.ToString());
}));
}
}
}
}
Parallel.Invoke(actionList.ToArray());
actionList.Clear();
_logger.LogWarning("*************** Sync loop is finished ***************");
await Task.Delay(60*1000, stoppingToken);
}
}
public async void GetHistory(RouterModel Router, PowerMeterModel Meter)
{
Web device = new() { IpAddress = Router.IpAddress, UserName = Meter.Username, Password = Meter.Password, Port = Meter.TcpPort };
StringBuilder SqlQuery = new();
StringBuilder TimeString = new();
ElnetMcMapping elnetMcMapping = new();
ElnetMcModel mcReadings = new();
if (Meter.ModelClass == nameof(ElnetMcModel).ToString())
{
for (int day = 1; day < 4; day++)
{
List<List<double>> responeData = new();
DateTime date = todayDate.AddDays(-day);
for (int j = 0; j < elnetMcMapping.DataItems.Count; j += 8)
{
var items = elnetMcMapping.DataItems.Skip(j).Take(8);
device.Items = items.Select(x => x.Address.ToString()).ToList();
var responseString = device.GetElnetReadings(httpClient, 2, date);
if (responseString != null)
{
int check = responeData.Count;
responeData.AddRange(JsonConvert.DeserializeObject<List<List<double>>>(responseString));
}
else { return; }
}
for (int j = 0; j < elnetMcMapping.DataItems.Count; j++) { elnetMcMapping.DataItems[j].Value = responeData[j]; }
foreach (MetaData metaData in elnetMcMapping.DataItems)
{
Type type = mcReadings.GetType();
PropertyInfo prop = type.GetProperty(metaData.Label);
if (prop.PropertyType == typeof(decimal)) { prop.SetValue(mcReadings, Convert.ToDecimal(metaData.Value[0]) * metaData.Multiplier, null); }
else if (prop.PropertyType == typeof(string)) { prop.SetValue(mcReadings, metaData.Value[0].ToString(), null); }
else if (prop.PropertyType == typeof(int)) { prop.SetValue(mcReadings, int.Parse(metaData.Value[0].ToString()), null); }
else if (prop.PropertyType == typeof(DateTime)) { prop.SetValue(mcReadings, DateTime.Now, null); }
else { return; }
}
var propList = mcReadings.GetType().GetProperties().ToList();
SqlQuery.Append("INSERT INTO " + Meter.DataTableName + " (");
foreach (PropertyInfo prop in propList) { SqlQuery.Append(prop.Name + ","); }
SqlQuery.Remove(SqlQuery.Length - 1, 1);
SqlQuery.Append(") VALUES (");
foreach (PropertyInfo prop in propList)
{
if (prop.PropertyType == typeof(DateTime))
{
DateTime dateTime = (DateTime)prop.GetValue(mcReadings);
SqlQuery.Append("'" + dateTime.ToString("yyyy-MM-dd HH:mm:ss") + "'" + ",");
}
else { SqlQuery.Append(prop.GetValue(mcReadings).ToString() + ","); }
}
SqlQuery.Remove(SqlQuery.Length - 1, 1);
SqlQuery.Append(");");
await dataAccess.SaveData(SqlQuery.ToString(), mcReadings, _config.GetConnectionString("PwrMeterDb"));
}
}
}
}
}
上面的代码应该只添加 4 MySql 行,而不是我得到 6,看起来整个方法
每次循环都重新开始 for (int day = 1; day < 4; day++)
改变它的价值。
我得到 6 行而不是 4 行(每天一行)
我得到 10 行而不是 5 行(每天一行)
而不是得到 6 行(每天一行)我得到 15
而不是得到 7 行(每天一行)我得到 21
有什么想法是错误的吗?
您没有在每个循环开始时清除 SqlQuery
StringBuilder
对象。
因此,在第一次迭代中,它有一个 INSERT
查询。在第二次迭代中,它有两个,总共三个 INSERT。在第三次迭代中,它有三个,总共六个。在第四次迭代中,它有四个 INSERT,总共十个。这会产生您正在观察的 1、3、6、10、15、21 序列。
在每个循环开始时调用 SqlQuery.Clear()
。