diff --git a/AsbCloudApp/Comparators/TelemetryUserDtoComparer.cs b/AsbCloudApp/Comparators/TelemetryUserDtoComparer.cs
index ad8f3239..42ed1e86 100644
--- a/AsbCloudApp/Comparators/TelemetryUserDtoComparer.cs
+++ b/AsbCloudApp/Comparators/TelemetryUserDtoComparer.cs
@@ -3,8 +3,10 @@ using System.Collections.Generic;
namespace AsbCloudApp.Comparators
{
+ ///
public class TelemetryUserDtoComparer : IEqualityComparer
{
+ ///
public bool Equals(TelemetryUserDto prevUser, TelemetryUserDto nextUser)
{
if (prevUser is null || nextUser is null)
@@ -15,6 +17,7 @@ namespace AsbCloudApp.Comparators
return false;
}
+ ///
public int GetHashCode(TelemetryUserDto user) => user.Id.GetHashCode();
}
}
diff --git a/AsbCloudApp/Data/ClusterDto.cs b/AsbCloudApp/Data/ClusterDto.cs
index 1f2eb2c7..8a9a95e6 100644
--- a/AsbCloudApp/Data/ClusterDto.cs
+++ b/AsbCloudApp/Data/ClusterDto.cs
@@ -2,15 +2,43 @@
namespace AsbCloudApp.Data
{
+#nullable enable
+ ///
+ /// DTO кустов
+ ///
public class ClusterDto : IMapPoint, IId
{
+ ///
public int Id { get; set; }
- public string Caption { get; set; }
+
+ ///
+ /// Название
+ ///
+ public string Caption { get; set; } = null!;
+
+ ///
public double? Latitude { get; set; }
+
+ ///
public double? Longitude { get; set; }
- public SimpleTimezoneDto Timezone { get; set; }
+
+ ///
+ public SimpleTimezoneDto Timezone { get; set; } = null!;
+
+ ///
+ /// ИД месторождения, необязательный
+ ///
public int? IdDeposit { get; set; }
- public DepositBaseDto Deposit { get; set; }
- public IEnumerable Wells { get; set; }
+
+ ///
+ /// DTO месторождения
+ ///
+ public DepositBaseDto? Deposit { get; set; }
+
+ ///
+ /// Список скважин куста
+ ///
+ public IEnumerable Wells { get; set; } = null!;
}
+#nullable disable
}
diff --git a/AsbCloudApp/Data/ClusterRopStatDto.cs b/AsbCloudApp/Data/ClusterRopStatDto.cs
index 92af0004..abc8de19 100644
--- a/AsbCloudApp/Data/ClusterRopStatDto.cs
+++ b/AsbCloudApp/Data/ClusterRopStatDto.cs
@@ -1,8 +1,18 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// ()
+ ///
public class ClusterRopStatDto
{
+ ///
+ /// .
+ ///
public double RopMax { get; set; }
+
+ ///
+ ///
+ ///
public double RopAverage { get; set; }
}
}
\ No newline at end of file
diff --git a/AsbCloudApp/Data/CompanyDto.cs b/AsbCloudApp/Data/CompanyDto.cs
index 38b6f9fc..b7698e36 100644
--- a/AsbCloudApp/Data/CompanyDto.cs
+++ b/AsbCloudApp/Data/CompanyDto.cs
@@ -1,11 +1,26 @@
namespace AsbCloudApp.Data
{
-
+ ///
+ /// DTO компании
+ ///
public class CompanyDto : IId
{
+ ///
public int Id { get; set; }
+
+ ///
+ /// Название
+ ///
public string Caption { get; set; }
+
+ ///
+ /// ИД типа компании
+ ///
public int IdCompanyType { get; set; }
+
+ ///
+ /// Название типа компании
+ ///
public string CompanyTypeCaption { get; set; }
}
}
diff --git a/AsbCloudApp/Data/CompanyTypeDto.cs b/AsbCloudApp/Data/CompanyTypeDto.cs
index 00926724..a2a83697 100644
--- a/AsbCloudApp/Data/CompanyTypeDto.cs
+++ b/AsbCloudApp/Data/CompanyTypeDto.cs
@@ -1,8 +1,16 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// DTO тип компании
+ ///
public class CompanyTypeDto : IId
{
+ ///
public int Id { get; set; }
+
+ ///
+ /// Название типа компании
+ ///
public string Caption { get; set; }
}
diff --git a/AsbCloudApp/Data/DatesRangeDto.cs b/AsbCloudApp/Data/DatesRangeDto.cs
index 8df4776b..64a01263 100644
--- a/AsbCloudApp/Data/DatesRangeDto.cs
+++ b/AsbCloudApp/Data/DatesRangeDto.cs
@@ -2,9 +2,19 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// Диапазон дат
+ ///
public class DatesRangeDto
{
+ ///
+ /// Дата начала диапазона
+ ///
public DateTime From { get; set; }
+
+ ///
+ /// Дата окончания диапазона
+ ///
public DateTime To { get; set; }
}
}
diff --git a/AsbCloudApp/Data/DepositDto.cs b/AsbCloudApp/Data/DepositDto.cs
index be0200fd..d15c2048 100644
--- a/AsbCloudApp/Data/DepositDto.cs
+++ b/AsbCloudApp/Data/DepositDto.cs
@@ -2,17 +2,37 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// DTO Месторождения
+ ///
public class DepositBaseDto : IMapPoint, IId
{
+ ///
public int Id { get; set; }
+
+ ///
+ /// Название
+ ///
public string Caption { get; set; }
+
+ ///
public double? Latitude { get; set; }
+
+ ///
public double? Longitude { get; set; }
+
+ ///
public SimpleTimezoneDto Timezone { get; set; }
}
+ ///
+ /// DTO Месторождения с кустами
+ ///
public class DepositDto : DepositBaseDto
{
+ ///
+ /// Кусты месторождения
+ ///
public IEnumerable Clusters { get; set; }
}
}
diff --git a/AsbCloudApp/Data/DrillFlowChartDto.cs b/AsbCloudApp/Data/DrillFlowChartDto.cs
index 55e14919..af6dfe8d 100644
--- a/AsbCloudApp/Data/DrillFlowChartDto.cs
+++ b/AsbCloudApp/Data/DrillFlowChartDto.cs
@@ -7,6 +7,9 @@ namespace AsbCloudApp.Data
///
public class DrillFlowChartDto : IId
{
+ ///
+ ///
+ ///
public int Id { get; set; }
///
diff --git a/AsbCloudApp/Data/DrillingProgramPartDto.cs b/AsbCloudApp/Data/DrillingProgramPartDto.cs
index f2714de9..9800bad4 100644
--- a/AsbCloudApp/Data/DrillingProgramPartDto.cs
+++ b/AsbCloudApp/Data/DrillingProgramPartDto.cs
@@ -2,9 +2,19 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// Часть программы бурения
+ ///
public class DrillingProgramPartDto
{
+ ///
+ /// Название
+ ///
public string Name { get; set; }
+
+ ///
+ /// ИД категории файла
+ ///
public int IdFileCategory { get; set; }
///
@@ -13,10 +23,30 @@ namespace AsbCloudApp.Data
/// 2 - completely approved
///
public int IdState { get; set; }
+
+ ///
+ /// Публикаторы. Могут загружать файл этой категории
+ ///
public IEnumerable Publishers { get; set; }
+
+ ///
+ /// Согласованты. Могут согласовывать загруженные файлы этой категории
+ ///
public IEnumerable Approvers { get; set; }
+
+ ///
+ /// Разрешение для текущего пользователя согласовывать документ
+ ///
public bool PermissionToApprove { get; set; }
+
+ ///
+ /// Разрешение для текущего пользователя загружать документ
+ ///
public bool PermissionToUpload { get; set; }
+
+ ///
+ /// Ссылка на документ.
+ ///
public FileInfoDto File { get; set; }
}
}
diff --git a/AsbCloudApp/Data/IId.cs b/AsbCloudApp/Data/IId.cs
index 77e45a4d..e5ad455e 100644
--- a/AsbCloudApp/Data/IId.cs
+++ b/AsbCloudApp/Data/IId.cs
@@ -1,7 +1,13 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// Интерфейс данных с Id
+ ///
public interface IId
{
+ ///
+ /// Идентификатор БД
+ ///
public int Id { get; set; }
}
}
diff --git a/AsbCloudApp/Data/IMapPoint.cs b/AsbCloudApp/Data/IMapPoint.cs
index 4ab08239..f71bd7fa 100644
--- a/AsbCloudApp/Data/IMapPoint.cs
+++ b/AsbCloudApp/Data/IMapPoint.cs
@@ -1,9 +1,23 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// точка на карте
+ ///
public interface IMapPoint
{
+ ///
+ /// Широта
+ ///
double? Latitude { get; set; }
+
+ ///
+ /// Широта
+ ///
double? Longitude { get; set; }
+
+ ///
+ /// Часовой пояс
+ ///
SimpleTimezoneDto Timezone { get; set; }
}
}
diff --git a/AsbCloudApp/Data/ITelemetryData.cs b/AsbCloudApp/Data/ITelemetryData.cs
index 61d70da7..2838aef0 100644
--- a/AsbCloudApp/Data/ITelemetryData.cs
+++ b/AsbCloudApp/Data/ITelemetryData.cs
@@ -2,10 +2,19 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// Интерфейс записи данных телеметрии
+ ///
public interface ITelemetryData
{
+ ///
+ /// ИД телеметрии
+ ///
int IdTelemetry { get; set; }
+ ///
+ /// Отметка времени для этой записи
+ ///
DateTime DateTime { get; set; }
}
}
diff --git a/AsbCloudApp/Data/TelemetryDto.cs b/AsbCloudApp/Data/TelemetryDto.cs
index 804d7210..d71afdd4 100644
--- a/AsbCloudApp/Data/TelemetryDto.cs
+++ b/AsbCloudApp/Data/TelemetryDto.cs
@@ -2,16 +2,38 @@
namespace AsbCloudApp.Data
{
+ ///
+ /// DTO телеметрии панели
+ ///
public class TelemetryBaseDto : IId
{
+ ///
public int Id { get; set; }
+
+ ///
+ /// уникальный идентификатор телеметрии по которому панель оператора присылает данные
+ ///
public string RemoteUid { get; set; }
+
+ ///
+ /// информация о бурении, панели оператора и контроллерах
+ ///
public TelemetryInfoDto Info { get; set; }
}
+ ///
+ /// DTO телеметрии панели с скважиной
+ ///
public class TelemetryDto : TelemetryBaseDto
{
+ ///
+ /// ИД скважины
+ ///
public int? IdWell { get; set; }
+
+ ///
+ /// DTO скважины
+ ///
public WellInfoDto Well { get; set; }
}
}
diff --git a/AsbCloudApp/Data/WITS/Record1Dto.cs b/AsbCloudApp/Data/WITS/Record1Dto.cs
index ca79211d..28a0aaa2 100644
--- a/AsbCloudApp/Data/WITS/Record1Dto.cs
+++ b/AsbCloudApp/Data/WITS/Record1Dto.cs
@@ -14,7 +14,7 @@ namespace AsbCloudApp.Data.WITS
/// LongMnemonic = "DEPTBITM",
/// ShortMnemonic = "DBTM",
/// Description = "Depth Bit (meas)",
- /// Description2 = "Code indicating what activity is currently being performed on the rig. IT IS ESSENTIAL that this information be as accurate and current as possible. Acceptible codes are shownhere",
+ /// Description2 = "Code indicating what activity is currently being performed on the rig. IT IS ESSENTIAL that this information be as accurate and current as possible. Acceptable codes are shown here",
/// FPSUnits = "F",
/// MetricUnits = "M",
/// Length = 4,
@@ -103,7 +103,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 14,
/// LongMnemonic = "HKLA",
/// ShortMnemonic = "HKLA",
- /// Description = "Hookload (avg)",
+ /// Description = "Hook-load (avg)",
/// Description2 = "",
/// FPSUnits = "KLB",
/// MetricUnits = "KDN",
@@ -118,7 +118,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 15,
/// LongMnemonic = "HKLX",
/// ShortMnemonic = "HKLX",
- /// Description = "Hookload (max)",
+ /// Description = "Hook-load (max)",
/// Description2 = "",
/// FPSUnits = "KLB",
/// MetricUnits = "KDN",
@@ -508,7 +508,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 41,
/// LongMnemonic = "SPARE1",
/// ShortMnemonic = "SPR1",
- /// Description = "< SPARE 1>",
+ /// Description = "SPARE 1",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -523,7 +523,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 42,
/// LongMnemonic = "SPARE2",
/// ShortMnemonic = "SPR2",
- /// Description = "< SPARE 2>",
+ /// Description = "SPARE 2",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -538,7 +538,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 43,
/// LongMnemonic = "SPARE3",
/// ShortMnemonic = "SPR3",
- /// Description = "< SPARE 3>",
+ /// Description = "SPARE 3",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -553,7 +553,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 44,
/// LongMnemonic = "SPARE4",
/// ShortMnemonic = "SPR4",
- /// Description = "< SPARE 4>",
+ /// Description = "SPARE 4",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -568,7 +568,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 45,
/// LongMnemonic = "SPARE5",
/// ShortMnemonic = "SPR5",
- /// Description = "< SPARE 5>",
+ /// Description = "SPARE 5",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
diff --git a/AsbCloudApp/Data/WITS/Record7Dto.cs b/AsbCloudApp/Data/WITS/Record7Dto.cs
index 61c3f99d..43c370d1 100644
--- a/AsbCloudApp/Data/WITS/Record7Dto.cs
+++ b/AsbCloudApp/Data/WITS/Record7Dto.cs
@@ -224,7 +224,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 22,
/// LongMnemonic = "SPARE1",
/// ShortMnemonic = "SPR1",
- /// Description = "< SPARE 1>",
+ /// Description = "SPARE 1",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -239,7 +239,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 23,
/// LongMnemonic = "SPARE2",
/// ShortMnemonic = "SPR2",
- /// Description = "< SPARE 2>",
+ /// Description = "SPARE 2",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -254,7 +254,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 24,
/// LongMnemonic = "SPARE3",
/// ShortMnemonic = "SPR3",
- /// Description = "< SPARE 3>",
+ /// Description = "SPARE 3",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -269,7 +269,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 25,
/// LongMnemonic = "SPARE4",
/// ShortMnemonic = "SPR4",
- /// Description = "< SPARE 4>",
+ /// Description = "SPARE 4",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -284,7 +284,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 26,
/// LongMnemonic = "SPARE5",
/// ShortMnemonic = "SPR5",
- /// Description = "< SPARE 5>",
+ /// Description = "SPARE 5",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "---",
diff --git a/AsbCloudApp/Data/WITS/Record8Dto.cs b/AsbCloudApp/Data/WITS/Record8Dto.cs
index 38a83aad..7a8d7331 100644
--- a/AsbCloudApp/Data/WITS/Record8Dto.cs
+++ b/AsbCloudApp/Data/WITS/Record8Dto.cs
@@ -599,7 +599,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 47,
/// LongMnemonic = "SPARE1",
/// ShortMnemonic = "SPR1",
- /// Description = "< SPARE 1>",
+ /// Description = "SPARE 1",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -614,7 +614,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 48,
/// LongMnemonic = "SPARE2",
/// ShortMnemonic = "SPR2",
- /// Description = "< SPARE 2>",
+ /// Description = "SPARE 2",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -629,7 +629,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 49,
/// LongMnemonic = "SPARE3",
/// ShortMnemonic = "SPR3",
- /// Description = "< SPARE 3>",
+ /// Description = "SPARE 3",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -644,7 +644,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 50,
/// LongMnemonic = "SPARE4",
/// ShortMnemonic = "SPR4",
- /// Description = "< SPARE 4>",
+ /// Description = "SPARE 4",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -659,7 +659,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 51,
/// LongMnemonic = "SPARE5",
/// ShortMnemonic = "SPR5",
- /// Description = "< SPARE 5>",
+ /// Description = "SPARE 5",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "---",
@@ -674,7 +674,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 52,
/// LongMnemonic = "SPARE6",
/// ShortMnemonic = "SPR6",
- /// Description = "< SPARE 6>",
+ /// Description = "SPARE 6",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -689,7 +689,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 53,
/// LongMnemonic = "SPARE7",
/// ShortMnemonic = "SPR7",
- /// Description = "< SPARE 7>",
+ /// Description = "SPARE 7",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -704,7 +704,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 54,
/// LongMnemonic = "SPARE8",
/// ShortMnemonic = "SPR8",
- /// Description = "< SPARE 8>",
+ /// Description = "SPARE 8",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
@@ -719,7 +719,7 @@ namespace AsbCloudApp.Data.WITS
/// ItemId = 55,
/// LongMnemonic = "SPARE9",
/// ShortMnemonic = "SPR9",
- /// Description = "< SPARE 9>",
+ /// Description = "SPARE 9",
/// Description2 = "",
/// FPSUnits = "----",
/// MetricUnits = "----",
diff --git a/AsbCloudApp/Data/WellDto.cs b/AsbCloudApp/Data/WellDto.cs
index c1b9a22b..695c14c3 100644
--- a/AsbCloudApp/Data/WellDto.cs
+++ b/AsbCloudApp/Data/WellDto.cs
@@ -8,24 +8,16 @@ namespace AsbCloudApp.Data
///
public class WellDto : WellInfoDto, IMapPoint, IId
{
- ///
- /// ID в БД
- ///
+ ///
public int Id { get; set; }
- ///
- /// Широта
- ///
+ ///
public double? Latitude { get; set; }
- ///
- /// долгота
- ///
+ ///
public double? Longitude { get; set; }
- ///
- /// Упрощенная временная зона
- ///
+ ///
public SimpleTimezoneDto Timezone { get; set; }
///
diff --git a/AsbCloudApp/Services/ICrudService.cs b/AsbCloudApp/Services/ICrudService.cs
index aa1f8b41..5e0919b7 100644
--- a/AsbCloudApp/Services/ICrudService.cs
+++ b/AsbCloudApp/Services/ICrudService.cs
@@ -1,19 +1,71 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Services
{
+#nullable enable
+ ///
+ /// Сервис получения, добавления, изменения, удаления данных
+ ///
+ ///
public interface ICrudService
where Tdto : Data.IId
{
+ ///
+ /// Включение связных данных
+ ///
ISet Includes { get; }
+
+ ///
+ /// Добавление новой записи
+ ///
+ ///
+ ///
+ /// Id новой записи
Task InsertAsync(Tdto newItem, CancellationToken token = default);
+
+ ///
+ /// Добавление нескольких записей
+ ///
+ ///
+ ///
+ /// количество добавленных
Task InsertRangeAsync(IEnumerable newItems, CancellationToken token = default);
+
+ ///
+ /// Получение всех записей
+ ///
+ ///
+ ///
+ [Obsolete("Небезопасный метод, может выполняться бесконечно долго")]
Task> GetAllAsync(CancellationToken token = default);
- Task GetAsync(int id, CancellationToken token = default);
+
+ ///
+ /// Получить запись по id
+ ///
+ ///
+ ///
+ ///
+ Task GetAsync(int id, CancellationToken token = default);
+
+ ///
+ /// Отредактировать запись
+ ///
+ ///
+ ///
+ ///
+ ///
Task UpdateAsync(int id, Tdto item, CancellationToken token = default);
+
+ ///
+ /// Удалить запись
+ ///
+ ///
+ ///
+ ///
Task DeleteAsync(int id, CancellationToken token = default);
- Task DeleteAsync(IEnumerable ids, CancellationToken token = default);
}
+#nullable disable
}
\ No newline at end of file
diff --git a/AsbCloudInfrastructure/EfCache/EfCacheWithKeyExtensions.cs b/AsbCloudInfrastructure/EfCache/EfCacheDictionaryExtensions.cs
similarity index 100%
rename from AsbCloudInfrastructure/EfCache/EfCacheWithKeyExtensions.cs
rename to AsbCloudInfrastructure/EfCache/EfCacheDictionaryExtensions.cs
diff --git a/AsbCloudInfrastructure/Services/Cache/EfCacheL2.cs b/AsbCloudInfrastructure/Services/Cache/EfCacheL2.cs
deleted file mode 100644
index cd147d92..00000000
--- a/AsbCloudInfrastructure/Services/Cache/EfCacheL2.cs
+++ /dev/null
@@ -1,411 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace AsbCloudInfrastructure.Services.Cache
-{
-#nullable enable
- ///
- /// Кеширование запросов EF.
- ///
- public static class EfCacheL2
- {
- ///
- /// Кол-во обращений к БД.
- ///
- public static int CountOfRequestsToDB = 0;
- private static readonly Dictionary caches = new(16);
- private static readonly TimeSpan semaphoreTimeout = TimeSpan.FromSeconds(25);
- private static readonly SemaphoreSlim semaphore = new(1);
- private static readonly TimeSpan minCacheTime = TimeSpan.FromSeconds(2);
-
- private class CacheItem
- {
- internal IEnumerable? Data;
- internal DateTime DateObsolete;
- internal DateTime DateObsoleteTotal;
- internal readonly SemaphoreSlim semaphore = new(1);
- }
-
- private static CacheItem GetOrAddCache(string tag, Func valueFactory, TimeSpan obsolete)
- {
- CacheItem cache;
- while (!caches.ContainsKey(tag))
- {
- if (semaphore.Wait(0))
- {
- try {
- cache = new CacheItem();
-
- var dateObsolete = DateTime.Now + obsolete;
- var dateQueryStart = DateTime.Now;
- var data = valueFactory();
- var queryTime = DateTime.Now - dateQueryStart;
-
- if (dateObsolete - DateTime.Now < minCacheTime)
- dateObsolete = DateTime.Now + minCacheTime;
-
- cache.Data = data;
- cache.DateObsolete = dateObsolete;
- cache.DateObsoleteTotal = dateObsolete + queryTime + minCacheTime;
- caches.Add(tag, cache);
- }
- catch
- {
- throw;
- }
- finally
- {
- semaphore.Release();
- }
- break;
- }
- else
- {
- if (semaphore.Wait(semaphoreTimeout))
- {
- semaphore.Release();
- }
- else
- {
- semaphore.Release();
- throw new TimeoutException("EfCacheL2.GetOrAddCache. Can't wait too long while getting cache");
- }
- }
- }
-
- cache = caches[tag];
-
- if (cache.DateObsolete < DateTime.Now)
- {
- if (cache.semaphore.Wait(0))
- {
- try
- {
- var dateObsolete = DateTime.Now + obsolete;
- var dateQueryStart = DateTime.Now;
- var data = valueFactory();
- var queryTime = DateTime.Now - dateQueryStart;
-
- if (dateObsolete - DateTime.Now < minCacheTime)
- dateObsolete = DateTime.Now + minCacheTime;
-
- cache.Data = data;
- cache.DateObsolete = dateObsolete;
- cache.DateObsoleteTotal = dateObsolete + queryTime + minCacheTime;
- }
- catch
- {
- throw;
- }
- finally
- {
- cache.semaphore.Release();
- }
- }
- else if(cache.DateObsoleteTotal < DateTime.Now)
- {
- if (cache.semaphore.Wait(semaphoreTimeout))
- {
- cache.semaphore.Release();
- }
- else
- {
- cache.semaphore.Release();
- throw new TimeoutException("EfCacheL2.GetOrAddCache. Can't wait too long while getting cache");
- }
- }
- }
- return cache;
- }
-
- private static async Task GetOrAddCacheAsync(string tag, Func> valueFactoryAsync, TimeSpan obsolete, CancellationToken token)
- {
- CacheItem cache;
- while (!caches.ContainsKey(tag))
- {
- if (semaphore.Wait(0))
- {
- try
- {
- cache = new CacheItem();
-
- var dateObsolete = DateTime.Now + obsolete;
- var dateQueryStart = DateTime.Now;
- var data = await valueFactoryAsync(token);
- var queryTime = DateTime.Now - dateQueryStart;
-
- if (dateObsolete - DateTime.Now < minCacheTime)
- dateObsolete = DateTime.Now + minCacheTime;
-
- cache.Data = data;
- cache.DateObsolete = dateObsolete;
- cache.DateObsoleteTotal = dateObsolete + queryTime + minCacheTime;
- caches.Add(tag, cache);
- }
- catch
- {
- throw;
- }
- finally
- {
- semaphore.Release();
- }
- break;
- }
- else
- {
- if (await semaphore.WaitAsync(semaphoreTimeout, token))
- {
- semaphore.Release();
- }
- else
- {
- semaphore.Release();
- throw new TimeoutException("EfCacheL2.GetOrAddCache. Can't wait too long while getting cache");
- }
- }
- }
-
- cache = caches[tag];
-
- if (cache.DateObsolete < DateTime.Now)
- {
- if (cache.semaphore.Wait(0))
- {
- try
- {
- var dateObsolete = DateTime.Now + obsolete;
- var dateQueryStart = DateTime.Now;
- var data = await valueFactoryAsync(token);
- var queryTime = DateTime.Now - dateQueryStart;
-
- if (dateObsolete - DateTime.Now < minCacheTime)
- dateObsolete = DateTime.Now + minCacheTime;
-
- cache.Data = data;
- cache.DateObsolete = dateObsolete;
- cache.DateObsoleteTotal = dateObsolete + queryTime + minCacheTime;
- }
- catch
- {
- throw;
- }
- finally
- {
- cache.semaphore.Release();
- }
- }
- else if (cache.DateObsoleteTotal < DateTime.Now)
- {
- if (await cache.semaphore.WaitAsync(semaphoreTimeout, token))
- {
- cache.semaphore.Release();
- }
- else
- {
- cache.semaphore.Release();
- throw new TimeoutException("EfCacheL2.GetOrAddCache. Can't wait too long while getting updated cache");
- }
- }
- }
- return cache;
- }
-
- private static IEnumerable ConvertToIEnumerable(IEnumerable? data)
- {
- if (data is IEnumerable list)
- return list;
- else if (data is IDictionary dictionary)
- {
- System.Diagnostics.Trace.TraceWarning($"ConvertToIEnumerable. Use keyless method on keyed cache. Type: {typeof(T).Name};");
- return (IEnumerable)dictionary.Values;
- }
- else
- throw new NotSupportedException("cache.Data has wrong type.");
- }
-
- private static Dictionary ConvertToDictionary(IEnumerable? data, Func keySelector)
- where TKey : notnull
- {
- if (data is Dictionary dictionary)
- return dictionary;
- else if (data is IEnumerable enumerable)
- {
- System.Diagnostics.Trace.TraceWarning($"ConvertToDictionary. Use keyed method on keyless cache. Type: {typeof(T).Name};");
- return enumerable.ToDictionary(keySelector);
- }
- else
- throw new NotSupportedException("cache.Data has wrong type.");
- }
-
- ///
- /// Кешировать запрос в List\.
- /// Выборки по PK будут работать медленнее, чем при кешировании в виде словаря.
- ///
- ///
- ///
- /// Метка кеша
- /// Период устаревания данных
- ///
- public static IEnumerable FromCache(this IQueryable query, string tag, TimeSpan obsolescence)
- {
- IEnumerable factory ()
- {
- CountOfRequestsToDB++;
- return query.ToList();
- }
- var cache = GetOrAddCache(tag, factory, obsolescence);
- return ConvertToIEnumerable(cache.Data);
- }
-
- ///
- /// Асинхронно кешировать запрос в List\.
- /// Выборки по PK будут работать медленнее, чем при кешировании в виде словаря.
- ///
- ///
- ///
- /// Метка кеша
- /// Период устаревания данных
- ///
- ///
- public static async Task> FromCacheAsync(this IQueryable query, string tag, TimeSpan obsolescence, CancellationToken token = default)
- {
- async Task factory(CancellationToken token)
- {
- CountOfRequestsToDB++;
- return await query.ToListAsync(token);
- }
- var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
- return ConvertToIEnumerable(cache.Data);
- }
-
- ///
- /// Кешировать запрос в Dictionary\.
- ///
- /// тип ключа
- /// тип значения
- ///
- /// Метка кеша
- /// Период устаревания данных
- /// Делегат получения ключа из записи
- ///
- ///
- ///
- ///
- public static Dictionary FromCache(this IQueryable query, string tag, TimeSpan obsolescence, Func keySelector)
- where TKey: notnull
- {
- IEnumerable factory ()
- {
- CountOfRequestsToDB++;
- return query.ToDictionary(keySelector);
- }
- var cache = GetOrAddCache(tag, factory, obsolescence);
- return ConvertToDictionary(cache.Data, keySelector);
- }
-
- ///
- /// Асинхронно кешировать запрос в Dictionary\.
- ///
- /// тип ключа
- /// тип значения
- ///
- /// Метка кеша
- /// Период устаревания данных
- /// Делегат получения ключа из записи
- ///
- ///
- public static async Task> FromCacheAsync(this IQueryable query, string tag, TimeSpan obsolescence, Func keySelector, CancellationToken token = default)
- where TKey : notnull
- {
- async Task factory(CancellationToken token)
- {
- CountOfRequestsToDB++;
- return await query.ToDictionaryAsync(keySelector, token);
- }
- var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
- return ConvertToDictionary(cache.Data, keySelector);
- }
-
- ///
- /// Получить запись из кеша по ключу.
- /// При отсутствии кеша создаст его для всех записей из query.
- ///
- /// тип ключа
- /// тип значения
- ///
- /// Метка кеша
- /// Период устаревания данных
- /// Делегат получения ключа из записи
- ///
- ///
- /// if cache contains trash
- public static T? FromCacheGetValueOrDefault(this IQueryable query, string tag, TimeSpan obsolescence, Func keySelector, TKey key)
- where TKey : notnull
- {
- IEnumerable factory()
- {
- CountOfRequestsToDB++;
- return query.ToDictionary(keySelector);
- }
- var cache = GetOrAddCache(tag, factory, obsolescence);
- var data = cache.Data;
- if (data is Dictionary dictionary)
- return dictionary.GetValueOrDefault(key);
- else if (data is IEnumerable enumerable)
- {
- System.Diagnostics.Trace.TraceWarning($"Use keyed method on keyless cache. Tag: {tag}, type: {typeof(T).Name};");
- return enumerable.FirstOrDefault(v => keySelector(v).Equals(key));
- }
- else
- throw new NotSupportedException("cache.Data has wrong type.");
- }
-
- ///
- /// Асинхронно получить запись из кеша по ключу.
- /// При отсутствии кеша создаст его для всех записей из query.
- ///
- /// тип ключа
- /// тип значения
- ///
- /// Метка кеша
- /// Период устаревания данных
- /// Делегат получения ключа из записи
- ///
- ///
- ///
- /// if cache contains trash
- public static async Task FromCacheGetValueOrDefaultAsync(this IQueryable query, string tag, TimeSpan obsolescence, Func keySelector, TKey key, CancellationToken token = default)
- where TKey : notnull
- {
- async Task factory(CancellationToken token)
- {
- CountOfRequestsToDB++;
- return await query.ToDictionaryAsync(keySelector, token);
- }
- var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
-
- var data = cache.Data;
- if (data is Dictionary dictionary)
- return dictionary.GetValueOrDefault(key);
- else if (data is IEnumerable enumerable)
- {
- System.Diagnostics.Trace.TraceWarning($"Use keyed method on keyless cache. Tag: {tag}, type: {typeof(T).Name};");
- return enumerable.FirstOrDefault(v => keySelector(v).Equals(key));
- }
- else
- throw new NotSupportedException("cache.Data has wrong type.");
- }
-
- public static void DropCache(this IQueryable query, string tag)
- {
- caches.Remove(tag, out var _);
- }
- }
-#nullable disable
-}
diff --git a/AsbCloudInfrastructure/Services/CrudServiceBase.cs b/AsbCloudInfrastructure/Services/CrudServiceBase.cs
index 7bb64c88..d64ba451 100644
--- a/AsbCloudInfrastructure/Services/CrudServiceBase.cs
+++ b/AsbCloudInfrastructure/Services/CrudServiceBase.cs
@@ -124,15 +124,6 @@ namespace AsbCloudInfrastructure.Services
return context.SaveChangesAsync(token);
}
- public virtual Task DeleteAsync(IEnumerable ids, CancellationToken token = default)
- {
- var entities = dbSet.Where(e => ids.Contains(e.Id)).AsNoTracking();
- if (entities == default)
- return Task.FromResult(0);
- dbSet.RemoveRange(entities);
- return context.SaveChangesAsync(token);
- }
-
public virtual TDto Convert(TModel src) => src.Adapt();
public virtual TModel Convert(TDto src) => src.Adapt();
diff --git a/ConsoleApp1/Properties/launchSettings.json b/ConsoleApp1/Properties/launchSettings.json
new file mode 100644
index 00000000..33504c94
--- /dev/null
+++ b/ConsoleApp1/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "WSL": {
+ "commandName": "WSL2",
+ "distributionName": ""
+ }
+ }
+}
\ No newline at end of file