forked from ddrilling/AsbCloudServer
140 lines
4.9 KiB
C#
140 lines
4.9 KiB
C#
using AsbCloudApp.Data;
|
|
using AsbCloudApp.Services;
|
|
using AsbCloudDb.Model;
|
|
using AsbCloudInfrastructure.Services.Cache;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AsbCloudInfrastructure.Services
|
|
{
|
|
public abstract class TelemetryDataBaseService<TDto, TModel> : ITelemetryDataService<TDto>, IConverter<TDto, TModel>
|
|
where TDto : AsbCloudApp.Data.ITelemetryData
|
|
where TModel : class, AsbCloudDb.Model.ITelemetryData
|
|
{
|
|
private readonly IAsbCloudDbContext db;
|
|
private readonly ITelemetryService telemetryService;
|
|
|
|
protected readonly CacheTable<Telemetry> cacheTelemetry;
|
|
protected readonly CacheTable<TelemetryUser> cacheTelemetryUsers;
|
|
protected readonly CacheTable<Well> cacheWells;
|
|
|
|
public TelemetryDataBaseService(
|
|
IAsbCloudDbContext db,
|
|
ITelemetryService telemetryService,
|
|
CacheDb cacheDb)
|
|
{
|
|
this.db = db;
|
|
this.telemetryService = telemetryService;
|
|
|
|
cacheTelemetry = cacheDb.GetCachedTable<Telemetry>((AsbCloudDbContext)db);
|
|
cacheTelemetryUsers = cacheDb.GetCachedTable<TelemetryUser>((AsbCloudDbContext)db);
|
|
cacheWells = cacheDb.GetCachedTable<Well>((AsbCloudDbContext)db);
|
|
}
|
|
|
|
public virtual async Task<int> UpdateDataAsync(string uid, IEnumerable<TDto> dtos,
|
|
CancellationToken token = default)
|
|
{
|
|
if (dtos == default || !dtos.Any())
|
|
return 0;
|
|
|
|
var idTelemetry = telemetryService.GetOrCreateTemetryIdByUid(uid);
|
|
var dtoMinDate = dtos.Min(d => d.Date);
|
|
var dtoMaxDate = dtos.Max(d => d.Date);
|
|
|
|
telemetryService.SaveRequestDate(uid, dtoMaxDate);
|
|
|
|
var dataSet = db.Set<TModel>();
|
|
|
|
//var oldData = dataSet.Where(d=> d.IdTelemetry == idTelemetry
|
|
// && d.Date > dtoMinDate
|
|
// && d.Date < dtoMaxDate);
|
|
|
|
//dataSet.RemoveRange(oldData);
|
|
|
|
foreach (var dto in dtos)
|
|
{
|
|
dto.IdTelemetry = idTelemetry;
|
|
var data = Convert(dto);
|
|
data.Id = 0;
|
|
dataSet.Add(data);
|
|
}
|
|
|
|
return await db.SaveChangesAsync(token).ConfigureAwait(false);
|
|
}
|
|
|
|
public virtual async Task<IEnumerable<TDto>> GetAsync(int idWell,
|
|
DateTime dateBegin = default, double intervalSec = 600d,
|
|
int approxPointsCount = 1024, CancellationToken token = default)
|
|
{
|
|
var well = cacheWells.FirstOrDefault(w => w.Id == idWell);
|
|
if (well?.IdTelemetry is null)
|
|
return default;
|
|
|
|
if (dateBegin == default)
|
|
{
|
|
dateBegin = telemetryService.GetLastTelemetryDate(well.IdTelemetry ?? 0);
|
|
if (dateBegin != default)
|
|
dateBegin = dateBegin.AddSeconds(-intervalSec);
|
|
}
|
|
|
|
if (dateBegin == default)
|
|
dateBegin = DateTime.Now.AddSeconds(-intervalSec);
|
|
|
|
if (dateBegin.Kind == DateTimeKind.Unspecified)
|
|
dateBegin = DateTime.SpecifyKind(dateBegin, DateTimeKind.Utc);
|
|
|
|
var datEnd = dateBegin.AddSeconds(intervalSec);
|
|
var dbSet = db.Set<TModel>();
|
|
|
|
var query = from data in dbSet
|
|
where data.IdTelemetry == well.IdTelemetry
|
|
&& data.Date >= dateBegin && data.Date < datEnd
|
|
select data;
|
|
|
|
var fullDataCount = await query.CountAsync(token)
|
|
.ConfigureAwait(false);
|
|
|
|
if (fullDataCount == 0)
|
|
return default;
|
|
|
|
if (fullDataCount > 1.75 * approxPointsCount)
|
|
{
|
|
var m = (int)Math.Round(1d * fullDataCount / approxPointsCount);
|
|
if (m > 1)
|
|
query = query.Where(d => d.Id % m == 0);
|
|
}
|
|
|
|
var entities = await query
|
|
.OrderBy(d=>d.Date)
|
|
.AsNoTracking()
|
|
.ToListAsync(token)
|
|
.ConfigureAwait(false);
|
|
|
|
var dtos = entities.Select(e => Convert(e));
|
|
|
|
return dtos;
|
|
}
|
|
|
|
public virtual async Task<DatesRangeDto> GetDataDatesRangeAsync(int idWell,
|
|
CancellationToken token = default)
|
|
{
|
|
var telemetryId = telemetryService.GetIdTelemetryByIdWell(idWell);
|
|
if (telemetryId is null)
|
|
return null;
|
|
|
|
var (From, To) = await db.GetDatesRangeAsync<TModel>((int)telemetryId, token)
|
|
.ConfigureAwait(false);
|
|
|
|
return new DatesRangeDto { From = From, To = To };
|
|
}
|
|
|
|
public abstract TDto Convert(TModel src);
|
|
|
|
public abstract TModel Convert(TDto src);
|
|
}
|
|
}
|