fix and refactor WellService.

This commit is contained in:
Фролов 2021-12-22 11:41:18 +05:00
parent a9f03c2ecf
commit c5ed3c467f
12 changed files with 147 additions and 66 deletions

View File

@ -2,11 +2,15 @@
namespace AsbCloudApp.Data
{
public class TelemetryDto : IId
public class TelemetryBaseDto : IId
{
public int Id { get; set; }
public string RemoteUid { get; set; }
public TelemetryInfoDto Info { get; set; }
}
public class TelemetryDto : TelemetryBaseDto
{
public int? IdWell { get; set; }
public WellInfoDto Well { get; set; }
}

View File

@ -20,7 +20,7 @@ namespace AsbCloudApp.Data
public int IdState { get; set; }
public DateTime LastTelemetryDate { get; set; }
public int? IdTelemetry { get; set; }
public TelemetryDto Telemetry { get; set; }
public TelemetryBaseDto Telemetry { get; set; }
public IEnumerable<CompanyDto> Companies { get; set; }
}
}

View File

@ -7,7 +7,7 @@ namespace AsbCloudApp.Services
public interface ICrudService<Tdto>
where Tdto : Data.IId
{
List<string> Includes { get; }
ISet<string> Includes { get; }
Task<int> InsertAsync(Tdto newItem, CancellationToken token = default);
Task<int> InsertRangeAsync(IEnumerable<Tdto> newItems, CancellationToken token = default);
Task<IEnumerable<Tdto>> GetAllAsync(CancellationToken token = default);

33
AsbCloudApp/Tree.cs Normal file
View File

@ -0,0 +1,33 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsbCloudApp
{
public class Tree<T> : Dictionary<T, Tree<T>>
{
public Tree()
{}
public Tree(T key, Tree<T> node = null)
{
Add(key, node);
}
public Tree(Tree<T> other)
:base(other)
{}
public Tree(IEnumerable<T> keys)
{
foreach (var key in keys)
Add(key);
}
public void Add(T key) => Add(key, null);
}
}

View File

@ -437,27 +437,6 @@ namespace AsbCloudDb.Model
});
});
//modelBuilder.Entity<ModeType>(entity =>
//{
// entity.HasData(new List<ModeType>{
// new ModeType{ Id = 1, Caption = "Нагрузка" },
// new ModeType{ Id = 2, Caption = "Дифф. давление" },
// new ModeType{ Id = 3, Caption = "Момент на ВСП" },
// new ModeType{ Id = 4, Caption = "Обороты на ВСП" },
// new ModeType{ Id = 5, Caption = "Расход" }
// });
//});
}
public IQueryable<Well> GetWellsForCompany(int idCompany)
{
return from well in Wells
.Include(w => w.RelationCompaniesWells)
.ThenInclude(r => r.Company)
.Include(w => w.Cluster)
.ThenInclude(c => c.Deposit)
where well.RelationCompaniesWells.Any(c => c.IdCompany == idCompany)
select well;
}
public async Task<(DateTime From, DateTime To)> GetDatesRangeAsync<TEntity>(int idTelemetry,

View File

@ -64,7 +64,7 @@ namespace AsbCloudInfrastructure.Services
public async Task<IEnumerable<ClusterDto>> GetClustersAsync(int idCompany,
CancellationToken token = default)
{
var entities = await db.GetWellsForCompany(idCompany)
var entities = await GetWellsForCompany(idCompany)
.Select(e => e.Cluster)
.Distinct()
.AsNoTracking()
@ -79,7 +79,7 @@ namespace AsbCloudInfrastructure.Services
public async Task<IEnumerable<ClusterDto>> GetClustersAsync(int idCompany,
int depositId, CancellationToken token = default)
{
var entities = await db.GetWellsForCompany(idCompany)
var entities = await GetWellsForCompany(idCompany)
.Select(e => e.Cluster)
.Where(e => e.IdDeposit == depositId)
.Distinct()
@ -95,7 +95,7 @@ namespace AsbCloudInfrastructure.Services
public async Task<IEnumerable<WellDto>> GetWellsAsync(int idCompany,
int idCluster, CancellationToken token = default)
{
var entities = await db.GetWellsForCompany(idCompany)
var entities = await GetWellsForCompany(idCompany)
.Where(e => e.IdCluster == idCluster)
.AsNoTracking()
.ToListAsync(token)
@ -121,6 +121,16 @@ namespace AsbCloudInfrastructure.Services
.GroupBy(c => c.Key.Deposit);
}
private IQueryable<Well> GetWellsForCompany(int idCompany)
{
return db.Wells
.Include(w => w.RelationCompaniesWells)
.ThenInclude(r => r.Company)
.Include(w => w.Cluster)
.ThenInclude(c => c.Deposit)
.Where(w => w.RelationCompaniesWells.Any(c => c.IdCompany == idCompany));
}
private IEnumerable<DepositDto> CreateDepositDto(IEnumerable<IGrouping<Deposit,IGrouping<Cluster, Well>>>gDepositEntities)
{
return gDepositEntities.Select(gDeposit => new DepositDto

View File

@ -1,3 +1,4 @@
using AsbCloudApp;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.Cache;
@ -18,7 +19,7 @@ namespace AsbCloudInfrastructure.Services
private readonly IAsbCloudDbContext db;
private readonly CacheDb cacheDb;
public List<string> Includes { get; } = new ();
public ISet<string> Includes { get; } = new SortedSet<string>();
protected CacheTable<TModel> Cache {
get {

View File

@ -1,4 +1,5 @@
using AsbCloudApp.Data;
using AsbCloudApp;
using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Mapster;
@ -18,7 +19,7 @@ namespace AsbCloudInfrastructure.Services
protected readonly IAsbCloudDbContext context;
protected readonly DbSet<TModel> dbSet;
public List<string> Includes { get; } = new List<string>();
public ISet<string> Includes { get; } = new SortedSet<string>();
public CrudServiceBase(IAsbCloudDbContext context)
{

View File

@ -34,11 +34,9 @@ namespace AsbCloudInfrastructure.Services
public SetpointsService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService)
{
cacheSetpoints = cacheDb.GetCachedTable<SetpointsRequest>(
(AsbCloudDbContext)db,
new List<string> {
nameof(SetpointsRequest.Author),
nameof(SetpointsRequest.Well),
});
(AsbCloudDbContext)db,
nameof(SetpointsRequest.Author),
nameof(SetpointsRequest.Well));
this.telemetryService = telemetryService;
}
@ -125,7 +123,6 @@ namespace AsbCloudInfrastructure.Services
return 1;
}
public SetpointsRequest Convert(SetpointsRequestDto src)
{
var entity = src.Adapt<SetpointsRequest>();

View File

@ -16,9 +16,7 @@ namespace AsbCloudInfrastructure.Services
public class TelemetryService : ITelemetryService
{
private readonly CacheTable<Telemetry> cacheTelemetry;
private readonly CacheTable<Well> cacheWells;
private readonly CacheTable<Cluster> cacheClusters;
private readonly CacheTable<Deposit> cacheDeposits;
private readonly CacheTable<Well> cacheWells;//TODO: use wellService insad of this
private readonly IAsbCloudDbContext db;
private readonly ITelemetryTracker telemetryTracker;
private readonly ITimeZoneService timeZoneService;
@ -33,9 +31,12 @@ namespace AsbCloudInfrastructure.Services
CacheDb cacheDb)
{
cacheTelemetry = cacheDb.GetCachedTable<Telemetry>((AsbCloudDbContext)db);
cacheWells = cacheDb.GetCachedTable<Well>((AsbCloudDbContext)db);
cacheClusters = cacheDb.GetCachedTable<Cluster>((AsbCloudDbContext)db);
cacheDeposits = cacheDb.GetCachedTable<Deposit>((AsbCloudDbContext)db);
cacheWells = cacheDb.GetCachedTable<Well>(
(AsbCloudDbContext)db,
$"{nameof(Well.Cluster)}.{nameof(Cluster.Deposit)}",
nameof(Well.Telemetry),
$"{nameof(Well.RelationCompaniesWells)}.{nameof(RelationCompanyWell.Company)}",
nameof(Well.WellType));
this.db = db;
this.telemetryTracker = telemetryTracker;
this.timeZoneService = timeZoneService;
@ -185,21 +186,17 @@ namespace AsbCloudInfrastructure.Services
if (well is null)
return null;
if (well.Latitude is not null && well.Longitude is not null)
return (well.Latitude ?? default, well.Longitude??default);
var cluster = await cacheClusters.FirstOrDefaultAsync(c => c.Id == well.IdCluster, token)
.ConfigureAwait(false);
if (cluster.Latitude is not null && cluster.Longitude is not null)
return (cluster.Latitude ?? default, cluster.Longitude ?? default);
var deposit = await cacheDeposits.FirstOrDefaultAsync(d => d.Id == cluster.IdDeposit, token)
.ConfigureAwait(false);
if (deposit.Latitude is not null && deposit.Longitude is not null)
return (deposit.Latitude ?? default, deposit.Longitude ?? default);
var latitude = well.Latitude ??
well.Cluster?.Latitude ??
well.Cluster?.Deposit?.Latitude;
var longitude = well.Longitude ??
well.Cluster?.Longitude ??
well.Cluster?.Deposit?.Longitude;
if (latitude is not null && longitude is not null)
return ((double)latitude, (double)longitude);
return null;
}

View File

@ -15,8 +15,7 @@ namespace AsbCloudInfrastructure.Services
{
private readonly CacheTable<User> cacheUsers;
private readonly CacheTable<RelationUserUserRole> cacheRelationUserToRoles;
public List<string> Includes { get; }
public ISet<string> Includes { get; } = new SortedSet<string>();
public IUserRoleService RoleService { get; }
public UserService(IAsbCloudDbContext context, CacheDb cacheDb, IUserRoleService roleService)

View File

@ -3,7 +3,6 @@ using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.Cache;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
@ -13,15 +12,32 @@ using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services
{
public class WellService : CrudCacheServiceBase<WellDto, Well>, IWellService
{
{
private static readonly TypeAdapterConfig typeAdapterConfig = TypeAdapterConfig<WellDto, Well>
.NewConfig()
.Ignore(dst => dst.Cluster,
dst => dst.RelationCompaniesWells,
dst => dst.Telemetry,
dst => dst.WellComposites,
dst => dst.WellCompositeSrcs,
dst => dst.WellOperations,
dst => dst.WellType)
.Config;
private readonly ITelemetryService telemetryService;
private readonly CacheTable<RelationCompanyWell> cacheRelationCompaniesWells;
private readonly CacheTable<CompanyType> cacheCompanyWellTypes;
public WellService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService)
:base(db, cacheDb)
{
this.telemetryService = telemetryService;
cacheRelationCompaniesWells = cacheDb.GetCachedTable<RelationCompanyWell>((AsbCloudDbContext)db, nameof(RelationCompanyWell.Company), nameof(RelationCompanyWell.Well));
cacheCompanyWellTypes = cacheDb.GetCachedTable<CompanyType>((AsbCloudDbContext)db);
Includes.Add($"{nameof(Well.Cluster)}.{nameof(Cluster.Deposit)}");
Includes.Add(nameof(Well.Telemetry));
Includes.Add($"{nameof(Well.RelationCompaniesWells)}.{nameof(RelationCompanyWell.Company)}");
Includes.Add(nameof(Well.WellType));
}
public DateTime GetLastTelemetryDate(int idWell)
@ -39,15 +55,36 @@ namespace AsbCloudInfrastructure.Services
{
var relations = await cacheRelationCompaniesWells
.WhereAsync(r => r.IdCompany == idCompany, token);
var dtos = relations.Select(r => Convert(r.Well));
var wellsIds = relations.Select(r => r.IdWell);
var wells = await Cache.WhereAsync(w => wellsIds.Contains(w.Id));
var dtos = wells.Select(Convert);
return dtos;
}
public override Task<int> InsertAsync(WellDto newItem, CancellationToken token = default)
public override async Task<int> InsertAsync(WellDto dto, CancellationToken token = default)
{
throw new NotImplementedException();
implement this
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (dto.IdWellType is < 1 or > 2)
throw new ArgumentException("Тип скважины указан неправильно.", nameof(dto));
if (dto.IdState is < 0 or > 2)
throw new ArgumentException("Текущее состояние работы скважины указано неправильно.", nameof(dto));
if (dto.Id != 0 && await Cache.ContainsAsync(w => w.Id == dto.Id, token))
throw new ArgumentException($"Нельзя повторно добавить скважину с id: {dto.Id}", nameof(dto));
var entity = Convert(dto);
var result = await Cache.InsertAsync(entity, token);
if (dto.Companies.Any())
{
var newRelations = dto.Companies.Select(c => new RelationCompanyWell { IdWell = result.Id, IdCompany = c.Id });
await cacheRelationCompaniesWells.InsertAsync(newRelations, token);
}
return result.Id;
}
public override Task<int> InsertRangeAsync(IEnumerable<WellDto> dtos, CancellationToken token)
@ -69,7 +106,16 @@ namespace AsbCloudInfrastructure.Services
var entity = Convert(dto);
var oldRelations = await cacheRelationCompaniesWells.FirstOrDefaultAsync(w => w.Id == idWell, token);
var oldRelations = await cacheRelationCompaniesWells
.WhereAsync(r => r.IdWell == idWell, token);
if(dto.Companies.Count() != oldRelations.Count() ||
dto.Companies.Any(c => !oldRelations.Any(oldC => oldC.IdCompany == c.Id)))
{
await cacheRelationCompaniesWells.RemoveAsync(r => r.IdWell == idWell, token);
var newRelations = dto.Companies.Select(c=> new RelationCompanyWell {IdWell = idWell, IdCompany = c.Id });
await cacheRelationCompaniesWells.InsertAsync(newRelations, token);
}
var result = await Cache.UpsertAsync(entity, token);
return result;
@ -127,9 +173,21 @@ namespace AsbCloudInfrastructure.Services
return clusterWells.Select(w => w.Id);
}
protected override Well Convert(WellDto dto)
{
var entity = dto.Adapt<Well>(typeAdapterConfig);
//dto.WellType = entity.WellType?.Caption;
//dto.Cluster = entity.Cluster?.Caption;
//dto.Deposit = entity.Cluster?.Deposit?.Caption;
//dto.LastTelemetryDate = GetLastTelemetryDate(entity.Id);
//dto.Companies = GetCompanies(entity.Id);
return entity;
}
protected override WellDto Convert(Well entity)
{
var dto = base.Convert(entity);
dto.WellType = entity.WellType?.Caption;
dto.Cluster = entity.Cluster?.Caption;
dto.Deposit = entity.Cluster?.Deposit?.Caption;
dto.LastTelemetryDate = GetLastTelemetryDate(entity.Id);
@ -140,6 +198,8 @@ namespace AsbCloudInfrastructure.Services
private CompanyDto Convert(Company entity)
{
var dto = entity.Adapt<CompanyDto>();
dto.CompanyTypeCaption = entity.CompanyType?.Caption
?? cacheCompanyWellTypes.FirstOrDefault(c => c.Id == entity.IdCompanyType).Caption;
return dto;
}
}