feat(dal): UnitFilterService добавлена обработка cancellationToken
This commit is contained in:
@@ -23,7 +23,8 @@ namespace PARR.DAL.DomainServices.UnitFilterService
|
|||||||
/// <returns>Список ID Unit'ов</returns>
|
/// <returns>Список ID Unit'ов</returns>
|
||||||
Task<IEnumerable<Guid>?> GetUnitsIdByJobFilterAsync(
|
Task<IEnumerable<Guid>?> GetUnitsIdByJobFilterAsync(
|
||||||
Job job,
|
Job job,
|
||||||
int? takeCount = null);
|
int? takeCount = null,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получает отфильтрованные Unit'ы с полной информацией о значениях полей и связях.
|
/// Получает отфильтрованные Unit'ы с полной информацией о значениях полей и связях.
|
||||||
@@ -34,7 +35,8 @@ namespace PARR.DAL.DomainServices.UnitFilterService
|
|||||||
/// <returns>Список UnitFilterResultDto или null, если Job не найден</returns>
|
/// <returns>Список UnitFilterResultDto или null, если Job не найден</returns>
|
||||||
Task<IEnumerable<UnitFilterResultDto>?> GetUnitsByJobFilterAsync(
|
Task<IEnumerable<UnitFilterResultDto>?> GetUnitsByJobFilterAsync(
|
||||||
Guid jobId,
|
Guid jobId,
|
||||||
int? takeCount = null);
|
int? takeCount = null,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получает отфильтрованные Unit'ы с полной информацией о значениях полей и связях.
|
/// Получает отфильтрованные Unit'ы с полной информацией о значениях полей и связях.
|
||||||
@@ -45,7 +47,9 @@ namespace PARR.DAL.DomainServices.UnitFilterService
|
|||||||
/// <returns>Список UnitFilterResultDto</returns>
|
/// <returns>Список UnitFilterResultDto</returns>
|
||||||
Task<IEnumerable<UnitFilterResultDto>?> GetUnitsByJobFilterAsync(
|
Task<IEnumerable<UnitFilterResultDto>?> GetUnitsByJobFilterAsync(
|
||||||
Job job,
|
Job job,
|
||||||
int? takeCount = null);
|
int? takeCount = null,
|
||||||
|
CancellationToken cancellationToken = default
|
||||||
|
);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Получает имена связанных Unit'ов для заданного Unit, отфильтрованных по RelationshipFilters Job.
|
/// Получает имена связанных Unit'ов для заданного Unit, отфильтрованных по RelationshipFilters Job.
|
||||||
@@ -56,6 +60,8 @@ namespace PARR.DAL.DomainServices.UnitFilterService
|
|||||||
/// <returns>Список имён связанных Unit'ов (уникальные, без дублей)</returns>
|
/// <returns>Список имён связанных Unit'ов (уникальные, без дублей)</returns>
|
||||||
Task<List<string>> GetRelatedUnitNamesAsync(
|
Task<List<string>> GetRelatedUnitNamesAsync(
|
||||||
Guid jobId,
|
Guid jobId,
|
||||||
Guid unitId);
|
Guid unitId,
|
||||||
|
CancellationToken cancellationToken = default
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,21 +49,33 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<IEnumerable<UnitFilterResultDto>?> GetUnitsByJobFilterAsync(Guid jobId, int? takeCount = null)
|
public async Task<IEnumerable<UnitFilterResultDto>?> GetUnitsByJobFilterAsync(
|
||||||
|
Guid jobId,
|
||||||
|
int? takeCount = null,
|
||||||
|
CancellationToken cancellationToken = default
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var job = await LoadJobWithFiltersAsync(jobId);
|
var job = await LoadJobWithFiltersAsync(jobId);
|
||||||
return job == null ? null : await GetUnitsByJobFilterAsync(job, takeCount);
|
return job == null ? null : await GetUnitsByJobFilterAsync(job, takeCount, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<IEnumerable<Guid>?> GetUnitsIdByJobFilterAsync(Job job, int? takeCount = null)
|
public async Task<IEnumerable<Guid>?> GetUnitsIdByJobFilterAsync(
|
||||||
|
Job job,
|
||||||
|
int? takeCount = null,
|
||||||
|
CancellationToken cancellationToken = default
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var filteredUnits = await GetUnitsByJobFilterAsync(job, takeCount);
|
var filteredUnits = await GetUnitsByJobFilterAsync(job, takeCount, cancellationToken);
|
||||||
return filteredUnits?.Select(u => u.Id).ToList();
|
return filteredUnits?.Select(u => u.Id).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<IEnumerable<UnitFilterResultDto>?> GetUnitsByJobFilterAsync(Job job, int? takeCount = null)
|
public async Task<IEnumerable<UnitFilterResultDto>?> GetUnitsByJobFilterAsync(
|
||||||
|
Job job,
|
||||||
|
int? takeCount = null,
|
||||||
|
CancellationToken cancellationToken = default
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (job.Group == null)
|
if (job.Group == null)
|
||||||
throw new ArgumentNullException(nameof(job.Group), $"Job {job.Id} не содержит Group");
|
throw new ArgumentNullException(nameof(job.Group), $"Job {job.Id} не содержит Group");
|
||||||
@@ -92,7 +104,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
logger.LogDebug("Применение фильтра #{Index} (Id={FilterId})", i + 1, filter.Id);
|
logger.LogDebug("Применение фильтра #{Index} (Id={FilterId})", i + 1, filter.Id);
|
||||||
|
|
||||||
// 1. Найти ID юнитов по UnitFilter (Name LIKE)
|
// 1. Найти ID юнитов по UnitFilter (Name LIKE)
|
||||||
var initialUnitIds = await GetUnitIdsFromCacheOrDbAsync(filter);
|
var initialUnitIds = await GetUnitIdsFromCacheOrDbAsync(filter, cancellationToken);
|
||||||
if (!initialUnitIds.Any())
|
if (!initialUnitIds.Any())
|
||||||
{
|
{
|
||||||
logger.LogDebug("Фильтр #{Index}: пропущен (0 юнитов)", i + 1);
|
logger.LogDebug("Фильтр #{Index}: пропущен (0 юнитов)", i + 1);
|
||||||
@@ -102,13 +114,13 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (initialUnitIds.Contains(targetUnitId))
|
if (initialUnitIds.Contains(targetUnitId))
|
||||||
{
|
{
|
||||||
logger.LogDebug("🎯 DEBUG: Юнит {TargetUnitId} найден в initialUnitIds для фильтра #{Index}", targetUnitId, i + 1);
|
logger.LogDebug("DEBUG: Юнит {TargetUnitId} найден в initialUnitIds для фильтра #{Index}", targetUnitId, i + 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 2. Применить FieldFilters на уровне SQL
|
// 2. Применить FieldFilters на уровне SQL
|
||||||
var fieldStopwatch = Stopwatch.StartNew();
|
var fieldStopwatch = Stopwatch.StartNew();
|
||||||
var fieldFilteredIds = await ApplyFieldFiltersOnDbAsync(initialUnitIds, filter.FieldFilters);
|
var fieldFilteredIds = await ApplyFieldFiltersOnDbAsync(initialUnitIds, filter.FieldFilters, cancellationToken);
|
||||||
fieldStopwatch.Stop();
|
fieldStopwatch.Stop();
|
||||||
|
|
||||||
if (!fieldFilteredIds.Any())
|
if (!fieldFilteredIds.Any())
|
||||||
@@ -120,13 +132,13 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (initialUnitIds.Contains(targetUnitId) && !fieldFilteredIds.Contains(targetUnitId))
|
if (initialUnitIds.Contains(targetUnitId) && !fieldFilteredIds.Contains(targetUnitId))
|
||||||
{
|
{
|
||||||
logger.LogDebug("🎯 DEBUG: Юнит {TargetUnitId} ОТФИЛЬТРОВАН на этапе FieldFilters (Фильтр #{Index})", targetUnitId, i + 1);
|
logger.LogDebug("DEBUG: Юнит {TargetUnitId} ОТФИЛЬТРОВАН на этапе FieldFilters (Фильтр #{Index})", targetUnitId, i + 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 3. Применить RelationshipFilters на уровне SQL -> ВОЗВРАЩАЕТ FilteredUnitContext
|
// 3. Применить RelationshipFilters на уровне SQL -> ВОЗВРАЩАЕТ FilteredUnitContext
|
||||||
var relStopwatch = Stopwatch.StartNew();
|
var relStopwatch = Stopwatch.StartNew();
|
||||||
var relationshipFilteredContexts = await ApplyRelationshipFiltersOnDbAsync(fieldFilteredIds, filter.RelationshipFilters);
|
var relationshipFilteredContexts = await ApplyRelationshipFiltersOnDbAsync(fieldFilteredIds, filter.RelationshipFilters, cancellationToken);
|
||||||
relStopwatch.Stop();
|
relStopwatch.Stop();
|
||||||
|
|
||||||
if (!relationshipFilteredContexts.Any())
|
if (!relationshipFilteredContexts.Any())
|
||||||
@@ -139,7 +151,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
var targetContext = relationshipFilteredContexts.FirstOrDefault(c => c.UnitId == targetUnitId);
|
var targetContext = relationshipFilteredContexts.FirstOrDefault(c => c.UnitId == targetUnitId);
|
||||||
if (targetContext != null)
|
if (targetContext != null)
|
||||||
{
|
{
|
||||||
logger.LogDebug("🎯 DEBUG: Юнит {TargetUnitId} прошёл фильтр #{Index}. Родителей: {ParentCount}, Детей: {ChildCount}",
|
logger.LogDebug("DEBUG: Юнит {TargetUnitId} прошёл фильтр #{Index}. Родителей: {ParentCount}, Детей: {ChildCount}",
|
||||||
targetUnitId, i + 1, targetContext.ValidParentIds.Count, targetContext.ValidChildIds.Count);
|
targetUnitId, i + 1, targetContext.ValidParentIds.Count, targetContext.ValidChildIds.Count);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -194,7 +206,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
: targetBeforeUmbrella.ValidChildIds.Count;
|
: targetBeforeUmbrella.ValidChildIds.Count;
|
||||||
var passes = count >= (job.MinValueRelationships ?? 0) && count <= (job.MaxValueRelationships ?? int.MaxValue);
|
var passes = count >= (job.MinValueRelationships ?? 0) && count <= (job.MaxValueRelationships ?? int.MaxValue);
|
||||||
|
|
||||||
logger.LogDebug("🎯 DEBUG: Юнит {TargetUnitId} перед Umbrella: Count={Count}, Min={Min}, Max={Max}, Passes={Passes}",
|
logger.LogDebug("DEBUG: Юнит {TargetUnitId} перед Umbrella: Count={Count}, Min={Min}, Max={Max}, Passes={Passes}",
|
||||||
targetUnitId, count, job.MinValueRelationships, job.MaxValueRelationships, passes);
|
targetUnitId, count, job.MinValueRelationships, job.MaxValueRelationships, passes);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -207,7 +219,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
var targetAfterUmbrella = umbrellaFilteredContexts.FirstOrDefault(c => c.UnitId == targetUnitId);
|
var targetAfterUmbrella = umbrellaFilteredContexts.FirstOrDefault(c => c.UnitId == targetUnitId);
|
||||||
if (targetBeforeUmbrella != null && targetAfterUmbrella == null)
|
if (targetBeforeUmbrella != null && targetAfterUmbrella == null)
|
||||||
{
|
{
|
||||||
logger.LogDebug("🎯 DEBUG: Юнит {TargetUnitId} ОТФИЛЬТРОВАН на этапе Umbrella", targetUnitId);
|
logger.LogDebug("DEBUG: Юнит {TargetUnitId} ОТФИЛЬТРОВАН на этапе Umbrella", targetUnitId);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -252,7 +264,8 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<List<Guid>> ApplyFieldFiltersOnDbAsync(
|
private async Task<List<Guid>> ApplyFieldFiltersOnDbAsync(
|
||||||
List<Guid> unitIds,
|
List<Guid> unitIds,
|
||||||
IEnumerable<JobFieldFilter> fieldFilters)
|
IEnumerable<JobFieldFilter> fieldFilters,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (!fieldFilters.Any())
|
if (!fieldFilters.Any())
|
||||||
return unitIds;
|
return unitIds;
|
||||||
@@ -303,7 +316,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Выполняем промежуточный запрос для логирования
|
// Выполняем промежуточный запрос для логирования
|
||||||
var intermediateResult = await query.Select(u => u.Id).ToListAsync();
|
var intermediateResult = await query.Select(u => u.Id).ToListAsync(cancellationToken);
|
||||||
logger.LogDebug(" После фильтра #{Index}: осталось {Count} юнитов", filterIndex, intermediateResult.Count);
|
logger.LogDebug(" После фильтра #{Index}: осталось {Count} юнитов", filterIndex, intermediateResult.Count);
|
||||||
|
|
||||||
// Обновляем query для следующей итерации
|
// Обновляем query для следующей итерации
|
||||||
@@ -311,7 +324,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
.Where(u => intermediateResult.Contains(u.Id));
|
.Where(u => intermediateResult.Contains(u.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await query.Select(u => u.Id).ToListAsync();
|
var result = await query.Select(u => u.Id).ToListAsync(cancellationToken);
|
||||||
logger.LogDebug("ApplyFieldFiltersOnDbAsync: выход {UnitCount} юнитов", result.Count);
|
logger.LogDebug("ApplyFieldFiltersOnDbAsync: выход {UnitCount} юнитов", result.Count);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -326,7 +339,8 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<List<FilteredUnitContext>> ApplyRelationshipFiltersOnDbAsync(
|
private async Task<List<FilteredUnitContext>> ApplyRelationshipFiltersOnDbAsync(
|
||||||
List<Guid> unitIds,
|
List<Guid> unitIds,
|
||||||
IEnumerable<JobRelationshipFilter> relationshipFilters
|
IEnumerable<JobRelationshipFilter> relationshipFilters,
|
||||||
|
CancellationToken cancellationToken = default
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!relationshipFilters.Any() || !unitIds.Any())
|
if (!relationshipFilters.Any() || !unitIds.Any())
|
||||||
@@ -342,7 +356,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (unitIds.Contains(targetUnitId))
|
if (unitIds.Contains(targetUnitId))
|
||||||
{
|
{
|
||||||
logger.LogDebug("🎯 DEBUG: Юнит {TargetUnitId} присутствует во входных данных ApplyRelationshipFiltersOnDbAsync", targetUnitId);
|
logger.LogDebug("DEBUG: Юнит {TargetUnitId} присутствует во входных данных ApplyRelationshipFiltersOnDbAsync", targetUnitId);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -360,7 +374,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(link => unitIds.Contains(link.ChildUnitId))
|
.Where(link => unitIds.Contains(link.ChildUnitId))
|
||||||
.Select(link => new { ChildId = link.ChildUnitId, ParentId = link.ParentUnitId })
|
.Select(link => new { ChildId = link.ChildUnitId, ParentId = link.ParentUnitId })
|
||||||
.ToListAsync();
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
var allParentIds = allParentLinks.Select(l => l.ParentId).Distinct().ToList();
|
var allParentIds = allParentLinks.Select(l => l.ParentId).Distinct().ToList();
|
||||||
logger.LogDebug(" Найдено {ParentCount} уникальных родителей для {LinkCount} связей",
|
logger.LogDebug(" Найдено {ParentCount} уникальных родителей для {LinkCount} связей",
|
||||||
@@ -398,7 +412,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
v.FieldId == relFilter.FieldId &&
|
v.FieldId == relFilter.FieldId &&
|
||||||
EF.Functions.Like(v.Value.Value, dbValueMask)))
|
EF.Functions.Like(v.Value.Value, dbValueMask)))
|
||||||
.Select(u => u.Id)
|
.Select(u => u.Id)
|
||||||
.ToListAsync();
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
logger.LogDebug(" Найдено {MatchCount} родителей по маске", matchingParents.Count);
|
logger.LogDebug(" Найдено {MatchCount} родителей по маске", matchingParents.Count);
|
||||||
|
|
||||||
@@ -439,7 +453,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Where(link => unitIds.Contains(link.ParentUnitId))
|
.Where(link => unitIds.Contains(link.ParentUnitId))
|
||||||
.Select(link => new { ParentId = link.ParentUnitId, ChildId = link.ChildUnitId })
|
.Select(link => new { ParentId = link.ParentUnitId, ChildId = link.ChildUnitId })
|
||||||
.ToListAsync();
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
var allChildIds = allChildLinks.Select(l => l.ChildId).Distinct().ToList();
|
var allChildIds = allChildLinks.Select(l => l.ChildId).Distinct().ToList();
|
||||||
logger.LogDebug(" Найдено {ChildCount} уникальных детей для {LinkCount} связей",
|
logger.LogDebug(" Найдено {ChildCount} уникальных детей для {LinkCount} связей",
|
||||||
@@ -477,7 +491,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
v.FieldId == relFilter.FieldId &&
|
v.FieldId == relFilter.FieldId &&
|
||||||
EF.Functions.Like(v.Value.Value, dbValueMask)))
|
EF.Functions.Like(v.Value.Value, dbValueMask)))
|
||||||
.Select(u => u.Id)
|
.Select(u => u.Id)
|
||||||
.ToListAsync();
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
logger.LogDebug(" Найдено {MatchCount} детей по маске", matchingChildren.Count);
|
logger.LogDebug(" Найдено {MatchCount} детей по маске", matchingChildren.Count);
|
||||||
|
|
||||||
@@ -540,7 +554,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (context.UnitId == targetUnitId)
|
if (context.UnitId == targetUnitId)
|
||||||
{
|
{
|
||||||
logger.LogDebug("🎯 DEBUG Umbrella: Юнит {TargetUnitId}, Count={Count}, Min={Min}, Max={Max}, Passes={Passes}",
|
logger.LogDebug("DEBUG Umbrella: Юнит {TargetUnitId}, Count={Count}, Min={Min}, Max={Max}, Passes={Passes}",
|
||||||
targetUnitId, count, min, max, passes);
|
targetUnitId, count, min, max, passes);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -559,7 +573,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="contexts"></param>
|
/// <param name="contexts"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<List<UnitFilterResultDto>> LoadFinalResultAsync(List<FilteredUnitContext> contexts)
|
private async Task<List<UnitFilterResultDto>> LoadFinalResultAsync(List<FilteredUnitContext> contexts, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var allResults = new List<UnitFilterResultDto>();
|
var allResults = new List<UnitFilterResultDto>();
|
||||||
|
|
||||||
@@ -567,19 +581,19 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
var targetInContexts = contexts.FirstOrDefault(c => c.UnitId == targetUnitId);
|
var targetInContexts = contexts.FirstOrDefault(c => c.UnitId == targetUnitId);
|
||||||
if (targetInContexts != null)
|
if (targetInContexts != null)
|
||||||
{
|
{
|
||||||
logger.LogDebug("🎯 DEBUG: Юнит {TargetUnitId} передан в LoadFinalResultAsync. Родителей: {ParentCount}, Детей: {ChildCount}",
|
logger.LogDebug("DEBUG: Юнит {TargetUnitId} передан в LoadFinalResultAsync. Родителей: {ParentCount}, Детей: {ChildCount}",
|
||||||
targetUnitId, targetInContexts.ValidParentIds.Count, targetInContexts.ValidChildIds.Count);
|
targetUnitId, targetInContexts.ValidParentIds.Count, targetInContexts.ValidChildIds.Count);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.LogDebug("🎯 DEBUG: Юнит {TargetUnitId} НЕ передан в LoadFinalResultAsync", targetUnitId);
|
logger.LogDebug("DEBUG: Юнит {TargetUnitId} НЕ передан в LoadFinalResultAsync", targetUnitId);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < contexts.Count; i += batchSize)
|
for (int i = 0; i < contexts.Count; i += batchSize)
|
||||||
{
|
{
|
||||||
var batch = contexts.Skip(i).Take(batchSize).ToList();
|
var batch = contexts.Skip(i).Take(batchSize).ToList();
|
||||||
var batchResults = await LoadBatchAsync(batch);
|
var batchResults = await LoadBatchAsync(batch, cancellationToken);
|
||||||
allResults.AddRange(batchResults);
|
allResults.AddRange(batchResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,7 +606,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="batch"></param>
|
/// <param name="batch"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task<List<UnitFilterResultDto>> LoadBatchAsync(List<FilteredUnitContext> batch)
|
private async Task<List<UnitFilterResultDto>> LoadBatchAsync(List<FilteredUnitContext> batch, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var unitIds = batch.Select(c => c.UnitId).ToList();
|
var unitIds = batch.Select(c => c.UnitId).ToList();
|
||||||
var allParentIds = batch.SelectMany(c => c.ValidParentIds).Distinct().ToList();
|
var allParentIds = batch.SelectMany(c => c.ValidParentIds).Distinct().ToList();
|
||||||
@@ -603,7 +617,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
.AsSingleQuery()
|
.AsSingleQuery()
|
||||||
.Include(u => u.UnitValues).ThenInclude(v => v.Value)
|
.Include(u => u.UnitValues).ThenInclude(v => v.Value)
|
||||||
.Where(u => unitIds.Contains(u.Id))
|
.Where(u => unitIds.Contains(u.Id))
|
||||||
.ToDictionaryAsync(u => u.Id);
|
.ToDictionaryAsync(u => u.Id, cancellationToken);
|
||||||
|
|
||||||
// Загружаем родителей
|
// Загружаем родителей
|
||||||
Dictionary<Guid, Unit> parentsMap;
|
Dictionary<Guid, Unit> parentsMap;
|
||||||
@@ -613,7 +627,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
.AsSingleQuery()
|
.AsSingleQuery()
|
||||||
.Include(u => u.UnitValues).ThenInclude(v => v.Value)
|
.Include(u => u.UnitValues).ThenInclude(v => v.Value)
|
||||||
.Where(u => allParentIds.Contains(u.Id))
|
.Where(u => allParentIds.Contains(u.Id))
|
||||||
.ToDictionaryAsync(u => u.Id);
|
.ToDictionaryAsync(u => u.Id, cancellationToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -628,7 +642,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
.AsSingleQuery()
|
.AsSingleQuery()
|
||||||
.Include(u => u.UnitValues).ThenInclude(v => v.Value)
|
.Include(u => u.UnitValues).ThenInclude(v => v.Value)
|
||||||
.Where(u => allChildIds.Contains(u.Id))
|
.Where(u => allChildIds.Contains(u.Id))
|
||||||
.ToDictionaryAsync(u => u.Id);
|
.ToDictionaryAsync(u => u.Id, cancellationToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -681,14 +695,14 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<List<string>> GetRelatedUnitNamesAsync(Guid jobId, Guid unitId)
|
public async Task<List<string>> GetRelatedUnitNamesAsync(Guid jobId, Guid unitId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
logger.LogDebug("Начало GetRelatedUnitNamesAsync. JobId: {JobId}, UnitId: {UnitId}", jobId, unitId);
|
logger.LogDebug("Начало GetRelatedUnitNamesAsync. JobId: {JobId}, UnitId: {UnitId}", jobId, unitId);
|
||||||
|
|
||||||
var job = await jobService
|
var job = await jobService
|
||||||
.Get().AsNoTracking()
|
.Get().AsNoTracking()
|
||||||
.Include(j => j.UnitFilters).ThenInclude(uf => uf.RelationshipFilters)
|
.Include(j => j.UnitFilters).ThenInclude(uf => uf.RelationshipFilters)
|
||||||
.FirstOrDefaultAsync(j => j.Id == jobId);
|
.FirstOrDefaultAsync(j => j.Id == jobId, cancellationToken);
|
||||||
|
|
||||||
if (job == null)
|
if (job == null)
|
||||||
{
|
{
|
||||||
@@ -762,7 +776,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
var names = await unitService.Get().AsNoTracking()
|
var names = await unitService.Get().AsNoTracking()
|
||||||
.Where(u => matchingUnitIds.Contains(u.Id))
|
.Where(u => matchingUnitIds.Contains(u.Id))
|
||||||
.Select(u => u.Name)
|
.Select(u => u.Name)
|
||||||
.ToListAsync();
|
.ToListAsync(cancellationToken);
|
||||||
result.UnionWith(names);
|
result.UnionWith(names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -772,7 +786,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
|
|
||||||
#region вспомогательные методы
|
#region вспомогательные методы
|
||||||
|
|
||||||
private async Task<List<Guid>> GetUnitIdsFromCacheOrDbAsync(JobUnitFilter filter)
|
private async Task<List<Guid>> GetUnitIdsFromCacheOrDbAsync(JobUnitFilter filter, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var cacheKey = cacheService.GetKey(new[] { "uf_ids", filter.UnitFilter }, isUseHash: true);
|
var cacheKey = cacheService.GetKey(new[] { "uf_ids", filter.UnitFilter }, isUseHash: true);
|
||||||
|
|
||||||
@@ -785,7 +799,7 @@ internal class UnitFilterService : IUnitFilterService
|
|||||||
var initialUnitIds = await unitService.Get().AsNoTracking()
|
var initialUnitIds = await unitService.Get().AsNoTracking()
|
||||||
.Where(unit => EF.Functions.Like(unit.Name, filter.UnitFilter))
|
.Where(unit => EF.Functions.Like(unit.Name, filter.UnitFilter))
|
||||||
.Select(u => u.Id)
|
.Select(u => u.Id)
|
||||||
.ToListAsync();
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
var toCache = new UnitFilterIds
|
var toCache = new UnitFilterIds
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user