diff --git a/IoTSharp/Extensions/DataExtension.cs b/IoTSharp/Extensions/DataExtension.cs index 1d4447f18..0383e304d 100644 --- a/IoTSharp/Extensions/DataExtension.cs +++ b/IoTSharp/Extensions/DataExtension.cs @@ -66,6 +66,7 @@ internal static Dic PreparingData(this ApplicationDbContext _context, Diction { var tx = tl.First(); tx.FillKVToMe(kp); + // TODO:jy 待重新设计主键 tx.DateTime = DateTime.Now; _context.Set().Update(tx).State = EntityState.Modified; } diff --git a/IoTSharp/Storage/EFStorage.cs b/IoTSharp/Storage/EFStorage.cs index cc16eaca5..1d3bb8295 100644 --- a/IoTSharp/Storage/EFStorage.cs +++ b/IoTSharp/Storage/EFStorage.cs @@ -9,6 +9,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Dic = System.Collections.Generic.Dictionary; + namespace IoTSharp.Storage { @@ -17,8 +19,8 @@ public class EFStorage : IStorage private readonly AppSettings _appSettings; private readonly ILogger _logger; private readonly IServiceScopeFactory _scopeFactor; - private readonly IServiceScope scope; - private readonly ApplicationDbContext _context; + //private readonly IServiceScope scope; + //private readonly ApplicationDbContext _context; public EFStorage(ILogger logger, IServiceScopeFactory scopeFactor , IOptions options @@ -27,13 +29,16 @@ public class EFStorage : IStorage _appSettings = options.Value; _logger = logger; _scopeFactor = scopeFactor; - scope = scopeFactor.CreateScope(); - _context = scope.ServiceProvider.GetRequiredService(); + //scope = scopeFactor.CreateScope(); + //_context = scope.ServiceProvider.GetRequiredService(); } public Task> GetTelemetryLatest(Guid deviceId) { - var devid = from t in _context.TelemetryLatest + using var scope = _scopeFactor.CreateScope(); + using var context = scope.ServiceProvider.GetService(); + + var devid = from t in context.TelemetryLatest where t.DeviceId == deviceId select new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }; return devid.AsNoTracking().ToListAsync(); @@ -41,7 +46,10 @@ public Task> GetTelemetryLatest(Guid deviceId) public Task> GetTelemetryLatest(Guid deviceId, string keys) { - var devid = from t in _context.TelemetryLatest + using var scope = _scopeFactor.CreateScope(); + using var context = scope.ServiceProvider.GetService(); + + var devid = from t in context.TelemetryLatest where t.DeviceId == deviceId && keys.Split(',', ' ', ';').Contains(t.KeyName) select new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }; @@ -51,7 +59,10 @@ public Task> GetTelemetryLatest(Guid deviceId, string key public Task> LoadTelemetryAsync(Guid deviceId, string keys, DateTime begin) { - var kv = from t in _context.TelemetryData + using var scope = _scopeFactor.CreateScope(); + using var context = scope.ServiceProvider.GetService(); + + var kv = from t in context.TelemetryData where t.DeviceId == deviceId && keys.Split(',', ' ', ';').Contains(t.KeyName) && t.DateTime >= begin select new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }; return kv.AsNoTracking().ToListAsync(); @@ -59,7 +70,10 @@ public Task> LoadTelemetryAsync(Guid deviceId, string key public Task> LoadTelemetryAsync(Guid deviceId, string keys, DateTime begin, DateTime end) { - var kv = from t in _context.TelemetryData + using var scope = _scopeFactor.CreateScope(); + using var context = scope.ServiceProvider.GetService(); + + var kv = from t in context.TelemetryData where t.DeviceId == deviceId && keys.Split(',', ' ', ';').Contains(t.KeyName) && t.DateTime >= begin && t.DateTime < end select new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }; return kv.AsNoTracking().ToListAsync(); @@ -67,7 +81,10 @@ public Task> LoadTelemetryAsync(Guid deviceId, string key public Task> LoadTelemetryAsync(Guid deviceId, DateTime begin) { - var kv = from t in _context.TelemetryData + using var scope = _scopeFactor.CreateScope(); + using var context = scope.ServiceProvider.GetService(); + + var kv = from t in context.TelemetryData where t.DeviceId == deviceId && t.DateTime >= begin select new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }; return kv.AsNoTracking().ToListAsync(); @@ -75,7 +92,10 @@ public Task> LoadTelemetryAsync(Guid deviceId, DateTime b public Task> LoadTelemetryAsync(Guid deviceId, DateTime begin, DateTime end) { - var kv = from t in _context.TelemetryData + using var scope = _scopeFactor.CreateScope(); + using var context = scope.ServiceProvider.GetService(); + + var kv = from t in context.TelemetryData where t.DeviceId == deviceId && t.DateTime >= begin && t.DateTime < end select new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }; return kv.AsNoTracking().ToListAsync(); @@ -87,7 +107,7 @@ public virtual async Task<(bool result, List telemetries)> Store List telemetries = new List(); try { - using (var _scope = _scopeFactor.CreateScope()) + using (var scope = _scopeFactor.CreateScope()) { using (var _dbContext = scope.ServiceProvider.GetRequiredService()) { diff --git a/IoTSharp/Storage/ShardingStorage.cs b/IoTSharp/Storage/ShardingStorage.cs index 10e0637ba..99ccbb951 100644 --- a/IoTSharp/Storage/ShardingStorage.cs +++ b/IoTSharp/Storage/ShardingStorage.cs @@ -22,7 +22,7 @@ public class ShardingStorage : IStorage { private readonly AppSettings _appSettings; private readonly ILogger _logger; - private readonly IServiceScope scope; + //private readonly IServiceScope scope; private readonly IServiceScopeFactory _scopeFactor; @@ -32,7 +32,7 @@ public class ShardingStorage : IStorage { _appSettings = options.Value; _logger = logger; - scope = scopeFactor.CreateScope(); + //scope = scopeFactor.CreateScope(); _scopeFactor = scopeFactor; } @@ -40,11 +40,11 @@ public Task> GetTelemetryLatest(Guid deviceId) { try { - using (var _scope = _scopeFactor.CreateScope()) + using (var scope = _scopeFactor.CreateScope()) { - using (var _context = _scope.ServiceProvider.GetRequiredService()) + using (var context = scope.ServiceProvider.GetRequiredService()) { - var devid = from t in _context.TelemetryLatest + var devid = from t in context.TelemetryLatest where t.DeviceId == deviceId select new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }; @@ -63,11 +63,11 @@ public Task> GetTelemetryLatest(Guid deviceId, string key { try { - using (var _scope = _scopeFactor.CreateScope()) + using (var scope = _scopeFactor.CreateScope()) { - using (var _context = _scope.ServiceProvider.GetRequiredService()) + using (var context = scope.ServiceProvider.GetRequiredService()) { - var devid = from t in _context.TelemetryLatest + var devid = from t in context.TelemetryLatest where t.DeviceId == deviceId && keys.Split(',', ' ', ';').Contains(t.KeyName) select new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }; @@ -94,12 +94,12 @@ public Task> LoadTelemetryAsync(Guid deviceId, string key { try { - using (var _scope = _scopeFactor.CreateScope()) + using (var scope = _scopeFactor.CreateScope()) { - using (var _context = _scope.ServiceProvider.GetService()) + using (var context = scope.ServiceProvider.GetService()) { var lst = new List(); - var kv = _context.GetIShardingQueryable() + var kv = context.GetIShardingQueryable() .Where(t => t.DeviceId == deviceId && keys.Split(',', ' ', ';').Contains(t.KeyName) && t.DateTime >= begin && t.DateTime < end) .ToList().Select(t => new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }); return kv.ToList(); @@ -123,10 +123,12 @@ public Task> LoadTelemetryAsync(Guid deviceId, DateTime b { return Task.Run(() => { - using (var _context = scope.ServiceProvider.GetService()) + using var scope = _scopeFactor.CreateScope(); + + using (var context = scope.ServiceProvider.GetService()) { var lst = new List(); - var kv = _context.GetIShardingQueryable() + var kv = context.GetIShardingQueryable() .Where(t => t.DeviceId == deviceId && t.DateTime >= begin && t.DateTime < end) .ToList().Select(t => new TelemetryDataDto() { DateTime = t.DateTime, KeyName = t.KeyName, Value = t.ToObject() }); return kv.ToList(); @@ -141,6 +143,8 @@ public async Task<(bool result, List telemetries)> StoreTelemetry try { + using var scope = _scopeFactor.CreateScope(); + using (var db = scope.ServiceProvider.GetService()) { var lst = new List(); @@ -166,11 +170,11 @@ public async Task<(bool result, List telemetries)> StoreTelemetry try { - using (var _scope = _scopeFactor.CreateScope()) + using (var scope = _scopeFactor.CreateScope()) { - using (var _dbContext = _scope.ServiceProvider.GetRequiredService()) + using (var dbContext = scope.ServiceProvider.GetRequiredService()) { - var result1 = await _dbContext.SaveAsync(msg.MsgBody, msg.DeviceId, msg.DataSide); + var result1 = await dbContext.SaveAsync(msg.MsgBody, msg.DeviceId, msg.DataSide); result1.exceptions?.ToList().ForEach(ex => { _logger.LogError(ex.Value, $"{ex.Key} {ex.Value.Message} {ex.Value.InnerException?.Message}"); diff --git a/IoTSharp/Storage/TimescaleDBStorage.cs b/IoTSharp/Storage/TimescaleDBStorage.cs index 8675ca60f..ab48911ae 100644 --- a/IoTSharp/Storage/TimescaleDBStorage.cs +++ b/IoTSharp/Storage/TimescaleDBStorage.cs @@ -10,36 +10,45 @@ namespace IoTSharp.Storage { public class TimescaleDBStorage : EFStorage { - private readonly ApplicationDbContext _context; + //private readonly ApplicationDbContext _context; + + /// + /// 解决单例注入问题 jy + /// + readonly IServiceScopeFactory _scopeFactor; public TimescaleDBStorage(ILogger logger, IServiceScopeFactory scopeFactor , IOptions options ) : base(logger, scopeFactor, options) { - var scope = scopeFactor.CreateScope(); - _context = scope.ServiceProvider.GetRequiredService(); + //var scope = scopeFactor.CreateScope(); + //_context = scope.ServiceProvider.GetRequiredService(); + _scopeFactor = scopeFactor; } - private bool _needcrtate = false; + private volatile bool _needcrtate = false; - public override async Task<(bool result, List telemetries)> StoreTelemetryAsync(RawMsg msg) + public override Task<(bool result, List telemetries)> StoreTelemetryAsync(RawMsg msg) { if (!_needcrtate) { - var have = _context.Database.ExecuteScalar("SELECT count(0) FROM _timescaledb_catalog.hypertable where table_name='TelemetryData';"); + //解决单例注入问题 jy + using var scope = _scopeFactor.CreateScope(); + using var context = scope.ServiceProvider.GetRequiredService(); + var have = context.Database.ExecuteScalar("SELECT count(0) FROM _timescaledb_catalog.hypertable where table_name='TelemetryData';"); if (have == 0) { - _context.Database.ExecuteNonQuery("SELECT create_hypertable('\"TelemetryData\"', 'DateTime', 'DeviceId', 2, create_default_indexes=>FALSE);"); - _context.Database.ExecuteNonQuery("CREATE INDEX ON \"TelemetryData\" (\"KeyName\", \"DateTime\" DESC);"); - _context.Database.ExecuteNonQuery("CREATE INDEX ON \"TelemetryData\" (\"DataSide\", \"DateTime\" DESC);"); - _context.Database.ExecuteNonQuery("CREATE INDEX ON \"TelemetryData\" (\"Type\", \"DateTime\" DESC);"); + context.Database.ExecuteNonQuery("SELECT create_hypertable('\"TelemetryData\"', 'DateTime', 'DeviceId', 2, create_default_indexes=>FALSE);"); + context.Database.ExecuteNonQuery("CREATE INDEX ON \"TelemetryData\" (\"KeyName\", \"DateTime\" DESC);"); + context.Database.ExecuteNonQuery("CREATE INDEX ON \"TelemetryData\" (\"DataSide\", \"DateTime\" DESC);"); + context.Database.ExecuteNonQuery("CREATE INDEX ON \"TelemetryData\" (\"Type\", \"DateTime\" DESC);"); } else { _needcrtate = true; } } - return await base.StoreTelemetryAsync(msg); + return base.StoreTelemetryAsync(msg); } } } \ No newline at end of file