diff --git a/AsbCloudApp/Data/IWellRelated.cs b/AsbCloudApp/Data/IWellRelated.cs
index 28c42911..f79a03a9 100644
--- a/AsbCloudApp/Data/IWellRelated.cs
+++ b/AsbCloudApp/Data/IWellRelated.cs
@@ -8,6 +8,6 @@
///
/// Well id in db
///
- public int IdWell { get; set; }
+ int IdWell { get; set; }
}
}
diff --git a/AsbCloudApp/Services/ICrudService.cs b/AsbCloudApp/Services/ICrudService.cs
index 5e0919b7..8d5edb8d 100644
--- a/AsbCloudApp/Services/ICrudService.cs
+++ b/AsbCloudApp/Services/ICrudService.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
namespace AsbCloudApp.Services
{
#nullable enable
+
///
/// Сервис получения, добавления, изменения, удаления данных
///
@@ -14,9 +15,31 @@ namespace AsbCloudApp.Services
where Tdto : Data.IId
{
///
- /// Включение связных данных
+ /// Код возврата ошибки: Id не найден в БД.
///
- ISet Includes { get; }
+ public const int ErrorIdNotFound = -1;
+
+ ///
+ /// Получение всех записей
+ ///
+ ///
+ /// emptyList if nothing found
+ Task> GetAllAsync(CancellationToken token);
+
+ ///
+ /// Получить запись по id
+ ///
+ ///
+ ///
+ /// null if not found
+ Task GetAsync(int id, CancellationToken token);
+
+ ///
+ /// Получить запись по id
+ ///
+ ///
+ /// null if not found
+ Tdto? Get(int id);
///
/// Добавление новой записи
@@ -24,7 +47,7 @@ namespace AsbCloudApp.Services
///
///
/// Id новой записи
- Task InsertAsync(Tdto newItem, CancellationToken token = default);
+ Task InsertAsync(Tdto newItem, CancellationToken token);
///
/// Добавление нескольких записей
@@ -32,23 +55,7 @@ namespace AsbCloudApp.Services
///
///
/// количество добавленных
- Task InsertRangeAsync(IEnumerable newItems, CancellationToken token = default);
-
- ///
- /// Получение всех записей
- ///
- ///
- ///
- [Obsolete("Небезопасный метод, может выполняться бесконечно долго")]
- Task> GetAllAsync(CancellationToken token = default);
-
- ///
- /// Получить запись по id
- ///
- ///
- ///
- ///
- Task GetAsync(int id, CancellationToken token = default);
+ Task InsertRangeAsync(IEnumerable newItems, CancellationToken token);
///
/// Отредактировать запись
@@ -56,16 +63,16 @@ namespace AsbCloudApp.Services
///
///
///
- ///
- Task UpdateAsync(int id, Tdto item, CancellationToken token = default);
+ /// если больше 0 - Id записи, если меньше 0 - код ошибки
+ Task UpdateAsync(int id, Tdto item, CancellationToken token);
///
/// Удалить запись
///
///
///
- ///
- Task DeleteAsync(int id, CancellationToken token = default);
+ /// если больше 0 - Id записи, если меньше 0 - код ошибки
+ Task DeleteAsync(int id, CancellationToken token);
}
#nullable disable
}
\ No newline at end of file
diff --git a/AsbCloudApp/Services/IWellService.cs b/AsbCloudApp/Services/IWellService.cs
index 76cbf2a9..b655566a 100644
--- a/AsbCloudApp/Services/IWellService.cs
+++ b/AsbCloudApp/Services/IWellService.cs
@@ -21,6 +21,6 @@ namespace AsbCloudApp.Services
Task> GetClusterWellsIdsAsync(int idWell, CancellationToken token);
SimpleTimezoneDto GetTimezone(int idWell);
DatesRangeDto GetDatesRange(int idWell);
- void EnshureTimezonesIsSet();
+ Task EnshureTimezonesIsSetAsync(CancellationToken token);
}
}
diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs
index 48c3cb30..435e6418 100644
--- a/AsbCloudInfrastructure/DependencyInjection.cs
+++ b/AsbCloudInfrastructure/DependencyInjection.cs
@@ -47,6 +47,10 @@ namespace AsbCloudInfrastructure
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType()
.MapWith((source) => new(source));
+
+ TypeAdapterConfig.GlobalSettings.Default.Config
+ .ForType()
+ .MapWith((source) => new(source));
}
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
@@ -98,12 +102,27 @@ namespace AsbCloudInfrastructure
services.AddTransient();
// admin crud services:
- services.AddTransient, CrudServiceBase>(); // может быть включен в сервис TelemetryService
+ services.AddTransient, CrudServiceBase>(s =>
+ new CrudCacheServiceBase(
+ s.GetService(),
+ dbSet => dbSet.Include(t => t.Well))); // может быть включен в сервис TelemetryService
services.AddTransient, DrillParamsService>();
- services.AddTransient, CrudCacheServiceBase>();
- services.AddTransient, CrudCacheServiceBase>();
+ services.AddTransient, CrudCacheServiceBase>(s =>
+ new CrudCacheServiceBase(
+ s.GetService(),
+ dbSet => dbSet.Include(d => d.Clusters)));
+ services.AddTransient, CrudCacheServiceBase>(s =>
+ new CrudCacheServiceBase(
+ s.GetService(),
+ dbSet => dbSet.Include(c=>c.CompanyType)));
services.AddTransient, CrudCacheServiceBase>();
- services.AddTransient, CrudCacheServiceBase>(); // может быть включен в сервис ClusterService
+ services.AddTransient, CrudCacheServiceBase>(s =>
+ new CrudCacheServiceBase(
+ s.GetService(),
+ dbSet => dbSet
+ .Include(c => c.Wells)
+ .Include(c => c.Deposit))); // может быть включен в сервис ClusterService
+
services.AddTransient, CrudCacheServiceBase>();
// TelemetryData services
diff --git a/AsbCloudInfrastructure/EfCache/EfCacheDictionaryExtensions.cs b/AsbCloudInfrastructure/EfCache/EfCacheDictionaryExtensions.cs
index 347b9e17..9846f872 100644
--- a/AsbCloudInfrastructure/EfCache/EfCacheDictionaryExtensions.cs
+++ b/AsbCloudInfrastructure/EfCache/EfCacheDictionaryExtensions.cs
@@ -26,6 +26,57 @@ namespace AsbCloudInfrastructure.EfCache
internal DateTime DateObsolete;
internal DateTime DateObsoleteTotal;
internal readonly SemaphoreSlim semaphore = new(1);
+
+
+ internal Dictionary GetData()
+ where TKey : notnull
+ {
+ if (Data is Dictionary typedData)
+ return typedData;
+ throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ }
+
+ internal Dictionary GetData(Func convert, int attempt = 1)
+ where TKey : notnull
+ {
+ if (Data is Dictionary typedData)
+ return typedData;
+ if (Data is Dictionary typedEntityData)
+ {
+ if (semaphore.Wait(0))
+ {
+ try
+ {
+ var convertedData = typedEntityData.ToDictionary(i => i.Key, i => convert(i.Value));
+ Data = convertedData;
+ return convertedData;
+ }
+ catch
+ {
+ throw;
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+ else
+ {
+ if (semaphore.Wait(semaphoreTimeout))
+ {
+ semaphore.Release();
+ }
+ else
+ {
+ semaphore.Release();
+ throw new TimeoutException("EfCacheL2.GetOrAddCache. Can't wait too long while converting cache data");
+ }
+ }
+ }
+ if (attempt > 0)
+ return GetData(convert, --attempt);
+ throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ }
}
private static CacheItem GetOrAddCache(string tag, Func valueFactory, TimeSpan obsolete)
@@ -233,15 +284,9 @@ namespace AsbCloudInfrastructure.EfCache
where TKey : notnull
{
IDictionary factory()
- {
- var queryData = query.AsNoTracking()
- .ToDictionary(keySelector);
- return queryData;
- }
+ => query.AsNoTracking().ToDictionary(keySelector);
var cache = GetOrAddCache(tag, factory, obsolescence);
- if (cache.Data is Dictionary typedData)
- return typedData;
- throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ return cache.GetData();
}
///
@@ -267,17 +312,9 @@ namespace AsbCloudInfrastructure.EfCache
where TKey : notnull
{
IDictionary factory()
- {
- var queryData = query.AsNoTracking()
- .ToList();
- var data = queryData
- .ToDictionary(keySelector, convert);
- return data;
- }
+ => query.AsNoTracking().ToDictionary(keySelector);
var cache = GetOrAddCache(tag, factory, obsolescence);
- if (cache.Data is Dictionary typedData)
- return typedData;
- throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ return cache.GetData(convert);
}
///
@@ -301,15 +338,9 @@ namespace AsbCloudInfrastructure.EfCache
where TKey : notnull
{
async Task factory(CancellationToken token)
- {
- var queryData = await query.AsNoTracking().ToDictionaryAsync(keySelector, token);
- return queryData;
- }
+ => await query.AsNoTracking().ToDictionaryAsync(keySelector, token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
-
- if (cache.Data is Dictionary typedData)
- return typedData;
- throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ return cache.GetData();
}
///
@@ -331,16 +362,9 @@ namespace AsbCloudInfrastructure.EfCache
where TKey : notnull
{
async Task factory(CancellationToken token)
- {
- var queryData = await query.AsNoTracking().ToListAsync(token);
- var data = queryData.ToDictionary(keySelector, convert);
- return data;
- }
+ => await query.AsNoTracking().ToDictionaryAsync(keySelector, token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
-
- if (cache.Data is Dictionary typedData)
- return typedData;
- throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ return cache.GetData(convert);
}
///
diff --git a/AsbCloudInfrastructure/EfCache/EfCacheExtensions.cs b/AsbCloudInfrastructure/EfCache/EfCacheExtensions.cs
index beaf1001..e8c8a6e2 100644
--- a/AsbCloudInfrastructure/EfCache/EfCacheExtensions.cs
+++ b/AsbCloudInfrastructure/EfCache/EfCacheExtensions.cs
@@ -26,6 +26,54 @@ namespace AsbCloudInfrastructure.EfCache
internal DateTime DateObsolete;
internal DateTime DateObsoleteTotal;
internal readonly SemaphoreSlim semaphore = new(1);
+
+ internal IEnumerable GetData()
+ {
+ if (Data is IEnumerable typedData)
+ return typedData;
+ throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ }
+
+ internal IEnumerable GetData(Func convert, int attempt = 1)
+ {
+ if (Data is IEnumerable typedData)
+ return typedData;
+ if (Data is IEnumerable typedEntityData)
+ {
+ if (semaphore.Wait(0))
+ {
+ try
+ {
+ var convertedData = typedEntityData.Select(convert).ToList();
+ Data = convertedData;
+ return convertedData;
+ }
+ catch
+ {
+ throw;
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+ else
+ {
+ if (semaphore.Wait(semaphoreTimeout))
+ {
+ semaphore.Release();
+ }
+ else
+ {
+ semaphore.Release();
+ throw new TimeoutException("EfCacheL2.GetOrAddCache. Can't wait too long while converting cache data");
+ }
+ }
+ }
+ if(attempt > 0)
+ return GetData(convert, --attempt);
+ throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ }
}
private static CacheItem GetOrAddCache(string tag, Func valueFactory, TimeSpan obsolete)
@@ -224,16 +272,9 @@ namespace AsbCloudInfrastructure.EfCache
public static IEnumerable FromCache(this IQueryable query, string tag, TimeSpan obsolescence)
where TEntity : class
{
- IEnumerable factory()
- {
- var queryData = query.AsNoTracking()
- .ToList();
- return queryData;
- }
+ IEnumerable factory() => query.AsNoTracking().ToList();
var cache = GetOrAddCache(tag, factory, obsolescence);
- if(cache.Data is IEnumerable typedData)
- return typedData;
- throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ return cache.GetData();
}
///
@@ -250,19 +291,9 @@ namespace AsbCloudInfrastructure.EfCache
public static IEnumerable FromCache(this IQueryable query, string tag, TimeSpan obsolescence, Func convert)
where TEntity : class
{
- IEnumerable factory ()
- {
- var queryData = query.AsNoTracking()
- .ToList();
- var data = queryData
- .Select(convert)
- .ToList();
- return data;
- }
+ IEnumerable factory () => query.AsNoTracking().ToList();
var cache = GetOrAddCache(tag, factory, obsolescence);
- if (cache.Data is IEnumerable typedData)
- return typedData;
- throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ return cache.GetData(convert);
}
///
@@ -278,14 +309,9 @@ namespace AsbCloudInfrastructure.EfCache
where TEntity : class
{
async Task factory(CancellationToken token)
- {
- var queryData = await query.AsNoTracking().ToListAsync(token);
- return queryData;
- }
+ => await query.AsNoTracking().ToListAsync(token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
- if (cache.Data is IEnumerable typedData)
- return typedData;
- throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ return cache.GetData();
}
///
@@ -304,17 +330,9 @@ namespace AsbCloudInfrastructure.EfCache
where TEntity : class
{
async Task factory(CancellationToken token)
- {
- var queryData = await query.AsNoTracking().ToListAsync(token);
- var data = queryData
- .Select(convert)
- .ToList();
- return data;
- }
+ => await query.AsNoTracking().ToListAsync(token);
var cache = await GetOrAddCacheAsync(tag, factory, obsolescence, token);
- if (cache.Data is IEnumerable typedData)
- return typedData;
- throw new TypeAccessException("Cache data has wrong type. Possible 'tag' is not unique.");
+ return cache.GetData(convert);
}
///
diff --git a/AsbCloudInfrastructure/MapsterExtension.cs b/AsbCloudInfrastructure/MapsterExtension.cs
index 9f678a80..d86af842 100644
--- a/AsbCloudInfrastructure/MapsterExtension.cs
+++ b/AsbCloudInfrastructure/MapsterExtension.cs
@@ -6,35 +6,11 @@ namespace Mapster
{
public static class MapsterExtension
{
- public static IEnumerable Adapt(this IEnumerable