diff --git a/PARR.TemplateMatcher/PARR.TemplateMatcher.csproj b/PARR.TemplateMatcher/PARR.TemplateMatcher.csproj index a17ad3a6..fc46dc69 100644 --- a/PARR.TemplateMatcher/PARR.TemplateMatcher.csproj +++ b/PARR.TemplateMatcher/PARR.TemplateMatcher.csproj @@ -7,7 +7,6 @@ - diff --git a/PARR.TemplateMatcher/Services/Implementations/GroupedTemplateBuilder.cs b/PARR.TemplateMatcher/Services/Implementations/GroupedTemplateBuilder.cs index f4d4b654..32a869fc 100644 --- a/PARR.TemplateMatcher/Services/Implementations/GroupedTemplateBuilder.cs +++ b/PARR.TemplateMatcher/Services/Implementations/GroupedTemplateBuilder.cs @@ -24,10 +24,10 @@ internal class GroupedTemplateBuilder : IGroupedTemplateBuilder } public async Task> BuildAsync( - Dictionary> initialReverseMapping, - JobGroup jobGroup, - Job maxJob, - CancellationToken ct = default) + Dictionary> initialReverseMapping, + JobGroup jobGroup, + Job maxJob, + CancellationToken ct = default) { logger.LogDebug("Начало построения структуры групп для JobGroup {JobGroupId}.", jobGroup.Id); @@ -51,17 +51,21 @@ internal class GroupedTemplateBuilder : IGroupedTemplateBuilder var relevantUnitInValues = await unitInValueRepository.Get() .AsNoTracking() .Where(uiv => allSourceUnitIds.Contains(uiv.UnitId) && uiv.FieldId == groupingFieldId) + .OrderBy(uiv => uiv.UnitId) + .ThenBy(uiv => uiv.ValueId) .Select(uiv => new { uiv.UnitId, uiv.ValueId }) .ToListAsync(ct); var uivLookup = relevantUnitInValues .GroupBy(x => x.UnitId) - .ToDictionary(g => g.Key, g => g.Select(x => x.ValueId).ToList()); + .ToDictionary( + g => g.Key, + g => g.Select(x => x.ValueId).ToList()); // 4. Трансформируем в reverseMapping с парами var reverseMapping = new Dictionary>(); - foreach (var kvp in initialReverseMapping) + foreach (var kvp in initialReverseMapping.OrderBy(k => k.Key)) { var potentialUnitId = kvp.Key; var sourceDtoIds = kvp.Value; @@ -79,6 +83,8 @@ internal class GroupedTemplateBuilder : IGroupedTemplateBuilder var uniqueEntries = entries .GroupBy(e => (e.UnitId, e.UnitFieldValueId)) .Select(g => g.First()) + .OrderBy(e => e.UnitId) // ИСПРАВЛЕНО: стабильная сортировка + .ThenBy(e => e.UnitFieldValueId) .ToList(); if (uniqueEntries.Any()) @@ -94,7 +100,7 @@ internal class GroupedTemplateBuilder : IGroupedTemplateBuilder var innerGroupingValues = await unitInValueRepository.GetByUnitIdsAndFieldIdsAsync( allUnitIdsForInnerGrouping, - (new HashSet { innerGroupingFieldId }), + new HashSet { innerGroupingFieldId }, ct); var unitIdToInnerGroupingValueMap = innerGroupingValues @@ -105,7 +111,7 @@ internal class GroupedTemplateBuilder : IGroupedTemplateBuilder var templateGroups = new List(); int maxValueForSplitting = maxJob.MaxValueRelationships!.Value; - foreach (var kvp in reverseMapping) + foreach (var kvp in reverseMapping.OrderBy(k => k.Key)) { var potentialUnitId = kvp.Key; var unitsInTemplateForThisPotentialUnitId = kvp.Value; @@ -134,8 +140,13 @@ internal class GroupedTemplateBuilder : IGroupedTemplateBuilder foreach (var subGroupEntries in splitSubGroups) { + var sortedEntries = subGroupEntries + .OrderBy(e => e.UnitId) + .ThenBy(e => e.UnitFieldValueId) + .ToList(); + subGroups.Add(new GroupedTemplateSubGroup( - Entries: subGroupEntries, + Entries: sortedEntries, InnerGroupName: innerGroupName, GlobalIndex: globalIndex ));