Refactor TelemetryAnalysis.

This commit is contained in:
Фролов 2021-10-01 15:44:56 +05:00
parent 28b60250be
commit ae9b23cc00
11 changed files with 191 additions and 184 deletions

View File

@ -23,7 +23,7 @@ namespace AsbCloudApp.Services
Task<IEnumerable<TelemetryOperationInfoDto>> GetOperationsToIntervalAsync(int idWell, Task<IEnumerable<TelemetryOperationInfoDto>> GetOperationsToIntervalAsync(int idWell,
int intervalHoursTimestamp, int workBeginTimestamp, int intervalHoursTimestamp, int workBeginTimestamp,
CancellationToken token = default); CancellationToken token = default);
void CalculateAnalytics(); Task AnalyzeAndSaveTelemetriesAsync(CancellationToken token = default);
Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell, Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell,
CancellationToken token = default); CancellationToken token = default);
} }

View File

@ -19,8 +19,6 @@ namespace AsbCloudDb.Model
[Column("id_operation")] [Column("id_operation")]
public int IdOperation { get; set; } public int IdOperation { get; set; }
[JsonIgnore] [JsonIgnore]
[ForeignKey(nameof(IdTelemetry))] [ForeignKey(nameof(IdTelemetry))]
[InverseProperty(nameof(Model.Telemetry.Analysis))] [InverseProperty(nameof(Model.Telemetry.Analysis))]
@ -31,7 +29,6 @@ namespace AsbCloudDb.Model
[InverseProperty(nameof(Model.WellOperationCategory.Analysis))] [InverseProperty(nameof(Model.WellOperationCategory.Analysis))]
public virtual WellOperationCategory Operation { get; set; } public virtual WellOperationCategory Operation { get; set; }
[Column("unix_date", TypeName = "bigint"), Comment("Unix timestamp для Linq запросов с вычислением дат")] [Column("unix_date", TypeName = "bigint"), Comment("Unix timestamp для Linq запросов с вычислением дат")]
public long UnixDate { get; set; } public long UnixDate { get; set; }

View File

@ -2,6 +2,7 @@
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services; using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Services.Analysis;
using AsbCloudInfrastructure.Services.Cache; using AsbCloudInfrastructure.Services.Cache;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;

View File

@ -0,0 +1,16 @@
using System;
namespace AsbCloudInfrastructure.Services.Analysis
{
class DataSaubAnalyse
{
public int IdTelemetry { get; internal set; }
public DateTime Date { get; internal set; }
public double WellDepth { get; internal set; }
public double BitDepth { get; internal set; }
public double BlockPosition { get; internal set; }
public double RotorSpeed { get; internal set; }
public double Pressure { get; internal set; }
public double HookWeight { get; internal set; }
}
}

View File

@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services.Analysis
{ {
public class InterpolationLine public class InterpolationLine
{ {
@ -14,11 +14,15 @@ namespace AsbCloudInfrastructure.Services
public InterpolationLine(IEnumerable<(double Y, double X)> rawData) public InterpolationLine(IEnumerable<(double Y, double X)> rawData)
{ {
xSum = rawData.Sum(d => d.X); var iterator = rawData.GetEnumerator();
ySum = rawData.Sum(d => d.Y); while (iterator.MoveNext())
xySum = rawData.Sum(d => d.X * d.Y); {
x2Sum = rawData.Sum(d => d.X * d.X); xSum += iterator.Current.X;
count = rawData.Count(); ySum += iterator.Current.Y;
xySum += iterator.Current.X * iterator.Current.Y;
x2Sum += iterator.Current.X * iterator.Current.X;
count++;
}
} }
public double A => public double A =>
@ -29,7 +33,6 @@ namespace AsbCloudInfrastructure.Services
(xSum * xySum - x2Sum * ySum) / (xSum * xySum - x2Sum * ySum) /
(xSum * xSum - count * x2Sum); (xSum * xSum - count * x2Sum);
public bool IsYNotChanges(double upperBound = 0d, double lowerBound = 0d) => public bool IsYNotChanges(double upperBound = 0d, double lowerBound = 0d) =>
A < upperBound && A > lowerBound; A < upperBound && A > lowerBound;

View File

@ -4,15 +4,15 @@ using System.Threading.Tasks;
using System.Diagnostics; using System.Diagnostics;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services.Cache; using AsbCloudInfrastructure.Services.Cache;
using AsbCloudDb.Model; using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services.Analysis
{ {
public class TelemetryAnalyticsBackgroundService : BackgroundService public class TelemetryAnalyticsBackgroundService : BackgroundService
{ {
private readonly CacheDb cacheDb; private readonly CacheDb cacheDb;
private readonly TimeSpan period = TimeSpan.FromHours(1);
public TelemetryAnalyticsBackgroundService(CacheDb cacheDb) public TelemetryAnalyticsBackgroundService(CacheDb cacheDb)
{ {
@ -22,32 +22,32 @@ namespace AsbCloudInfrastructure.Services
protected override async Task ExecuteAsync(CancellationToken token = default) protected override async Task ExecuteAsync(CancellationToken token = default)
{ {
var timeToStartAnalysis = DateTime.Now; var timeToStartAnalysis = DateTime.Now;
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
.Options;
while (!token.IsCancellationRequested) while (!token.IsCancellationRequested)
{ {
if(DateTime.Now > timeToStartAnalysis) if(DateTime.Now > timeToStartAnalysis)
{ {
timeToStartAnalysis = DateTime.Now + period;
try try
{ {
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
.Options;
using var context = new AsbCloudDbContext(options); using var context = new AsbCloudDbContext(options);
var telemetryService = new TelemetryService(context, cacheDb); var telemetryService = new TelemetryService(context, cacheDb);
var analyticsService = new TelemetryAnalyticsService(context, var analyticsService = new TelemetryAnalyticsService(context,
telemetryService, cacheDb); telemetryService, cacheDb);
timeToStartAnalysis = DateTime.Now.AddHours(1); await analyticsService.AnalyzeAndSaveTelemetriesAsync(token).ConfigureAwait(false);
context.ChangeTracker.Clear();
await Task.Run(() => analyticsService.CalculateAnalytics(), token) context.Dispose();
.ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
Trace.TraceError(ex.Message); Trace.TraceError(ex.Message);
Console.WriteLine(ex.Message); Console.WriteLine(ex.Message);
} }
GC.Collect();
} }
var ms = (int)(timeToStartAnalysis - DateTime.Now).TotalMilliseconds; var ms = (int)(timeToStartAnalysis - DateTime.Now).TotalMilliseconds;

View File

@ -9,7 +9,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services.Analysis
{ {
public class TelemetryAnalyticsService : ITelemetryAnalyticsService public class TelemetryAnalyticsService : ITelemetryAnalyticsService
{ {
@ -19,7 +19,7 @@ namespace AsbCloudInfrastructure.Services
private readonly TelemetryOperationDetectorService operationDetectorService; private readonly TelemetryOperationDetectorService operationDetectorService;
private readonly IEnumerable<WellOperationCategory> operations; private readonly IEnumerable<WellOperationCategory> operations;
private const int intervalHours = 12; private const int countOfRecordsForInterpolation = 12 * 60 * 60;
public TelemetryAnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService, public TelemetryAnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService,
CacheDb cacheDb) CacheDb cacheDb)
@ -230,72 +230,70 @@ namespace AsbCloudInfrastructure.Services
return groupedOperationsList; return groupedOperationsList;
} }
public void CalculateAnalytics() public async Task AnalyzeAndSaveTelemetriesAsync(CancellationToken token = default)
{ {
var allTelemetryIds = (from telemetry in db.TelemetryDataSaub var allTelemetryIds = await db.TelemetryDataSaub
select telemetry.IdTelemetry) .Select(t => t.IdTelemetry)
.Distinct() .Distinct()
.ToList(); .ToListAsync(token)
.ConfigureAwait(false);
foreach(var idTelemetry in allTelemetryIds) foreach(var idTelemetry in allTelemetryIds)
{ {
var analyzeStartDate = GetAnalyzeStartDate(idTelemetry); var analyzeStartDate = await GetLastAnalysisDateAsync(idTelemetry, token).ConfigureAwait(false);
await AnalyseAndSaveTelemetryAsync(idTelemetry, analyzeStartDate, token).ConfigureAwait(false);
GC.Collect();
}
}
if (analyzeStartDate == default) private async Task AnalyseAndSaveTelemetryAsync(int idTelemetry, DateTime analyzeStartDate, CancellationToken token = default)
continue; {
const int step = 10;
const int take = step * 2;
TelemetryAnalysis currentAnalysis = null; TelemetryAnalysis currentAnalysis = null;
while (TryGetDataSaubPart(idTelemetry, analyzeStartDate, while (true)
out var dataSaubPart))
{ {
analyzeStartDate = dataSaubPart.Last().Date; var dataSaubPart = await GetDataSaubPartOrDefaultAsync(idTelemetry, analyzeStartDate, token).ConfigureAwait(false);
if (dataSaubPart is null)
break;
var count = dataSaubPart.Count(); var count = dataSaubPart.Count();
var skip = 0; var skip = 0;
var step = 10;
var take = step * 2;
for(;skip < count; skip += step) if (step > count)
{ break;
var analyzingSaubs = dataSaubPart.Skip(skip).Take(take);
if (analyzingSaubs.Count() <= 1) analyzeStartDate = dataSaubPart.Last().Date;
for (; (skip + step) < count; skip += step)
{ {
continue; var dataSaubPartOfPart = dataSaubPart.Skip(skip).Take(take);
var telemetryAnalysis = GetDrillingAnalysis(dataSaubPartOfPart);
if (currentAnalysis is not null)
{
if (currentAnalysis.IdOperation == telemetryAnalysis.IdOperation)
currentAnalysis.DurationSec += telemetryAnalysis.DurationSec;
else
{
currentAnalysis.OperationEndDepth = dataSaubPartOfPart.LastOrDefault()?.WellDepth;
db.TelemetryAnalysis.Add(currentAnalysis);
currentAnalysis = null;
}
} }
var dataSaub = analyzingSaubs.First();
var telemetryAnalysis = new TelemetryAnalysis();
telemetryAnalysis = GetDrillingAnalysis(analyzingSaubs);
if (currentAnalysis is null) if (currentAnalysis is null)
{ {
currentAnalysis = telemetryAnalysis; currentAnalysis = telemetryAnalysis;
currentAnalysis.OperationStartDepth = dataSaub.WellDepth; currentAnalysis.OperationStartDepth = dataSaubPartOfPart.FirstOrDefault()?.WellDepth;
}
if (currentAnalysis.IdOperation == telemetryAnalysis.IdOperation)
{
currentAnalysis.DurationSec += telemetryAnalysis.DurationSec;
currentAnalysis.OperationEndDepth = dataSaub.WellDepth;
}
else
{
db.TelemetryAnalysis.Add(currentAnalysis);
currentAnalysis = telemetryAnalysis;
currentAnalysis.OperationStartDepth = dataSaub.WellDepth;
} }
} }
db.SaveChanges(); await db.SaveChangesAsync(token).ConfigureAwait(false);
GC.Collect(); GC.Collect();
} }
} }
}
public async Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell, public async Task<DatesRangeDto> GetOperationsDateRangeAsync(int idWell,
CancellationToken token = default) CancellationToken token = default)
@ -327,52 +325,48 @@ namespace AsbCloudInfrastructure.Services
}; };
} }
private DateTime GetAnalyzeStartDate(int idTelemetry) private async Task<DateTime> GetLastAnalysisDateAsync(int idTelemetry, CancellationToken token = default)
{ {
var lastAnalysisInDb = (from analysis in db.TelemetryAnalysis var lastAnalysisInDb = await (from analysis in db.TelemetryAnalysis
where analysis.IdTelemetry == idTelemetry where analysis.IdTelemetry == idTelemetry
orderby analysis.UnixDate orderby analysis.UnixDate
select analysis) select analysis)
.DefaultIfEmpty() .LastOrDefaultAsync(token)
.Last(); .ConfigureAwait(false);
var lastAnalysisUnixDate = lastAnalysisInDb?.UnixDate ?? default; DateTime lastAnalysisDate = default;
var analyzeStartDate = lastAnalysisUnixDate == default if(lastAnalysisInDb is not null)
? DateTimeOffset.MinValue lastAnalysisDate = DateTime.UnixEpoch.AddSeconds(lastAnalysisInDb.DurationSec + lastAnalysisInDb.UnixDate);
: DateTimeOffset.FromUnixTimeSeconds(lastAnalysisUnixDate);
var firstDataSaub = GetFirstSaub(analyzeStartDate.DateTime, idTelemetry); return lastAnalysisDate;
var firstSaubUtcTime = firstDataSaub?.Date.ToUniversalTime() ?? default;
return firstSaubUtcTime;
} }
private bool TryGetDataSaubPart(int idTelemetry, DateTime analyzeStartDate, private Task<List<DataSaubAnalyse>> GetDataSaubPartOrDefaultAsync(int idTelemetry, DateTime analyzeStartDate, CancellationToken token) =>
out IEnumerable<TelemetryDataSaub> dataSaubPart) db.TelemetryDataSaub
{ .Where(d =>
var query = (from ds in db.TelemetryDataSaub d.IdTelemetry == idTelemetry &&
where ds.IdTelemetry == idTelemetry d.Date > analyzeStartDate &&
&& ds.Date > analyzeStartDate d.BitDepth != null &&
orderby ds.Date d.BlockPosition != null &&
select ds) d.HookWeight != null &&
.Take(12 * 60* 60) d.Pressure != null &&
.AsNoTracking(); d.RotorSpeed != null &&
d.WellDepth != null
dataSaubPart = query.ToList(); )
.OrderBy(d => d.Date)
return dataSaubPart.Any(); .Take(countOfRecordsForInterpolation)
} .Select(d => new DataSaubAnalyse {
IdTelemetry = d.IdTelemetry,
private TelemetryDataSaub GetFirstSaub(DateTime analyzeStartDate, int idTelemetry) Date = d.Date,
{ BitDepth = d.BitDepth ?? 0,
return (from ds in db.TelemetryDataSaub BlockPosition = d.BlockPosition ?? 0,
where ds.IdTelemetry == idTelemetry HookWeight = d.HookWeight ?? 0,
&& ds.Date > analyzeStartDate.AddHours(intervalHours) Pressure = d.Pressure ?? 0,
orderby ds.Date RotorSpeed = d.RotorSpeed ?? 0,
select ds).FirstOrDefault(); WellDepth = d.WellDepth ?? 0,
} })
.ToListAsync(token);
private static IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> DivideOperationsByIntervalLength( private static IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> DivideOperationsByIntervalLength(
IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds) IEnumerable<(long IntervalStart, string OperationName, int OperationDuration)> operations, int intervalSeconds)
@ -471,28 +465,23 @@ namespace AsbCloudInfrastructure.Services
return groupedOperationsList; return groupedOperationsList;
} }
private TelemetryAnalysis GetDrillingAnalysis(IEnumerable<TelemetryDataSaub> dataSaubBases) private TelemetryAnalysis GetDrillingAnalysis(IEnumerable<DataSaubAnalyse> dataSaubPartOfPart)
{ {
var lastSaubDate = dataSaubBases.Last().Date; var dataSaubFirst = dataSaubPartOfPart.First();
var dataSaubLast = dataSaubPartOfPart.Last();
var saubWellDepths = dataSaubBases.Where(sw => sw.WellDepth is not null) var saubWellDepths = dataSaubPartOfPart.Select(s => (Y: (double)s.WellDepth,
.Select(s => (Y: (double)s.WellDepth, X: (s.Date - dataSaubFirst.Date).TotalSeconds));
X: (s.Date - dataSaubBases.First().Date).TotalSeconds)); var saubBitDepths = dataSaubPartOfPart.Select(s => (Y: (double)s.BitDepth,
var saubBitDepths = dataSaubBases.Where(sw => sw.BitDepth is not null) X: (s.Date - dataSaubFirst.Date).TotalSeconds));
.Select(s => (Y: (double)s.BitDepth, var saubBlockPositions = dataSaubPartOfPart.Select(s => (Y: (double)s.BlockPosition,
X: (s.Date - dataSaubBases.First().Date).TotalSeconds)); X: (s.Date - dataSaubFirst.Date).TotalSeconds));
var saubBlockPositions = dataSaubBases.Where(sw => sw.BlockPosition is not null) var saubRotorSpeeds = dataSaubPartOfPart.Select(s => (Y: (double)s.RotorSpeed,
.Select(s => (Y: (double)s.BlockPosition, X: (s.Date - dataSaubFirst.Date).TotalSeconds));
X: (s.Date - dataSaubBases.First().Date).TotalSeconds)); var saubPressures = dataSaubPartOfPart.Select(s => (Y: (double)s.Pressure,
var saubRotorSpeeds = dataSaubBases.Where(sw => sw.RotorSpeed is not null) X: (s.Date - dataSaubFirst.Date).TotalSeconds));
.Select(s => (Y: (double)s.RotorSpeed, var saubHookWeights = dataSaubPartOfPart.Select(s => (Y: (double)s.HookWeight,
X: (s.Date - dataSaubBases.First().Date).TotalSeconds)); X: (s.Date - dataSaubFirst.Date).TotalSeconds));
var saubPressures = dataSaubBases.Where(sw => sw.Pressure is not null)
.Select(s => (Y: (double)s.Pressure,
X: (s.Date - dataSaubBases.First().Date).TotalSeconds));
var saubHookWeights = dataSaubBases.Where(sw => sw.HookWeight is not null)
.Select(s => (Y: (double)s.HookWeight,
X: (s.Date - dataSaubBases.First().Date).TotalSeconds));
var wellDepthLine = new InterpolationLine(saubWellDepths); var wellDepthLine = new InterpolationLine(saubWellDepths);
var bitPositionLine = new InterpolationLine(saubBitDepths); var bitPositionLine = new InterpolationLine(saubBitDepths);
@ -501,16 +490,11 @@ namespace AsbCloudInfrastructure.Services
var pressureLine = new InterpolationLine(saubPressures); var pressureLine = new InterpolationLine(saubPressures);
var hookWeightLine = new InterpolationLine(saubHookWeights); var hookWeightLine = new InterpolationLine(saubHookWeights);
var IsBlockRising = blockPositionLine.IsYDecreases(-0.0001);
var IsBlockGoesDown = blockPositionLine.IsYIncreases(0.0001);
var IsBlockStandsStill = blockPositionLine.IsYNotChanges(0.0001, -0.0001);
var drillingAnalysis = new TelemetryAnalysis var drillingAnalysis = new TelemetryAnalysis
{ {
IdTelemetry = dataSaubBases.First().IdTelemetry, IdTelemetry = dataSaubFirst.IdTelemetry,
UnixDate = (long)(lastSaubDate - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds, UnixDate = (long)(dataSaubFirst.Date - DateTime.UnixEpoch).TotalSeconds,
DurationSec = (int)(dataSaubBases.Last().Date - DurationSec = (int)(dataSaubLast.Date - dataSaubFirst.Date).TotalSeconds,
dataSaubBases.ElementAt(dataSaubBases.Count() - 2).Date).TotalSeconds,
OperationStartDepth = null, OperationStartDepth = null,
OperationEndDepth = null, OperationEndDepth = null,
IsWellDepthDecreasing = wellDepthLine.IsYDecreases(-0.0001), IsWellDepthDecreasing = wellDepthLine.IsYDecreases(-0.0001),
@ -526,7 +510,7 @@ namespace AsbCloudInfrastructure.Services
IsPressureGt20 = pressureLine.IsAverageYMoreThanBound(20), IsPressureGt20 = pressureLine.IsAverageYMoreThanBound(20),
IsHookWeightNotChanges = hookWeightLine.IsYNotChanges(0.0001, -0.0001), IsHookWeightNotChanges = hookWeightLine.IsYNotChanges(0.0001, -0.0001),
IsHookWeightLt3 = hookWeightLine.IsAverageYLessThanBound(3), IsHookWeightLt3 = hookWeightLine.IsAverageYLessThanBound(3),
IdOperation = 1 IdOperation = default,
}; };
drillingAnalysis.IdOperation = drillingAnalysis.IdOperation =

View File

@ -1,9 +1,9 @@
using AsbCloudDb.Model; using AsbCloudDb.Model;
using System; using System;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services.Analysis
{ {
public class TelemetryOperationDetector class TelemetryOperationDetector
{ {
public int Order { get; set; } public int Order { get; set; }
public WellOperationCategory Operation { get; set; } public WellOperationCategory Operation { get; set; }

View File

@ -1,11 +1,10 @@
using AsbCloudApp.Data; using AsbCloudDb.Model;
using AsbCloudDb.Model;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace AsbCloudInfrastructure.Services namespace AsbCloudInfrastructure.Services.Analysis
{ {
public class TelemetryOperationDetectorService class TelemetryOperationDetectorService
{ {
private readonly IEnumerable<TelemetryOperationDetector> detectors; private readonly IEnumerable<TelemetryOperationDetector> detectors;

View File

@ -1,48 +1,48 @@
using AsbCloudApp.Data; //using AsbCloudApp.Data;
using AsbCloudApp.Services; //using AsbCloudApp.Services;
using AsbCloudDb.Model; //using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.Cache; //using AsbCloudInfrastructure.Services.Cache;
using Mapster; //using Mapster;
using Microsoft.EntityFrameworkCore; //using Microsoft.EntityFrameworkCore;
using System; //using System;
using System.Linq; //using System.Linq;
using System.Threading; //using System.Threading;
using System.Threading.Tasks; //using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services //namespace AsbCloudInfrastructure.Services
{ //{
public class _CachedCrudService<Tdto, TModel> : ICachedCrudService<Tdto> // public class _CachedCrudService<Tdto, TModel> : ICachedCrudService<Tdto>
where TModel : class, AsbCloudDb.Model.IId // where TModel : class, AsbCloudDb.Model.IId
where Tdto : AsbCloudApp.Data.IId // where Tdto : AsbCloudApp.Data.IId
{ // {
private readonly CacheTable<TModel> cache; // private readonly CacheTable<TModel> cache;
public _CachedCrudService(IAsbCloudDbContext db, Cache.CacheDb cacheDb) // public _CachedCrudService(IAsbCloudDbContext db, Cache.CacheDb cacheDb)
{ // {
cache = cacheDb.GetCachedTable<TModel>((DbContext)db); // cache = cacheDb.GetCachedTable<TModel>((DbContext)db);
} // }
public virtual async Task<PaginationContainer<Tdto>> GetAsync(int skip = 0, int take = 32, CancellationToken token = default) // public virtual async Task<PaginationContainer<Tdto>> GetAsync(int skip = 0, int take = 32, CancellationToken token = default)
{ // {
var count = cache.Count(); // var count = cache.Count();
var result = new PaginationContainer<Tdto> { Skip = skip, Take = take, Count = count }; // var result = new PaginationContainer<Tdto> { Skip = skip, Take = take, Count = count };
if (count <= skip) // if (count <= skip)
return result; // return result;
var items = await cache.WhereAsync(token).ConfigureAwait(false); // var items = await cache.WhereAsync(token).ConfigureAwait(false);
result.Items.AddRange(items.OrderBy(i => i.Id).Skip(skip).Take(take).Select(i => Convert(i))); // result.Items.AddRange(items.OrderBy(i => i.Id).Skip(skip).Take(take).Select(i => Convert(i)));
return result; // return result;
} // }
public virtual Task<Tdto> GetAsync(int id, CancellationToken token = default) // public virtual Task<Tdto> GetAsync(int id, CancellationToken token = default)
{ // {
throw new NotImplementedException(); // throw new NotImplementedException();
} // }
public virtual Tdto Convert(TModel src) => src.Adapt<Tdto>(); // public virtual Tdto Convert(TModel src) => src.Adapt<Tdto>();
public virtual TModel Convert(Tdto src) => src.Adapt<TModel>(); // public virtual TModel Convert(Tdto src) => src.Adapt<TModel>();
} // }
} //}

View File

@ -25,15 +25,22 @@ namespace ConsoleApp1
var options = new DbContextOptionsBuilder<AsbCloudDbContext>() var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True") .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
.Options; .Options;
var db = new AsbCloudDbContext(options); using var db = new AsbCloudDbContext(options);
var cacheDb = new CacheDb();
var telemetryService = new TelemetryService(db, cacheDb);
var analyticsService = new TelemetryAnalyticsService(db,
telemetryService, cacheDb);
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
analyticsService.AnalyzeAndSaveTelemetriesAsync().Wait();
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
return;
var ts = new TelemetryService(db, new CacheDb()); var ts = new TelemetryService(db, new CacheDb());
var groups = ts.GetRedundentRemoteUids(); var groups = ts.GetRedundentRemoteUids();
foreach(var g in groups) foreach(var g in groups)
ts.Merge(g.Ids); ts.Merge(g.Ids);
//var sql = "UPDATE t_telemetry SET info = '{{\"a\":6}}' WHERE id = 2;\n" +
// "UPDATE t_telemetry SET info = '{{\"a\":1}}' WHERE id = 1;\n";
//db.Database.ExecuteSqlRaw(sql, 1);
Console.WriteLine("Done. Press any key to quit."); Console.WriteLine("Done. Press any key to quit.");
Console.ReadKey(); Console.ReadKey();