fix(templateMatcher): Устранено лишнее обновление шаблонов из-за нестабильной сортировки юнитов

This commit is contained in:
Mikhail Kuznetsov
2026-05-21 10:46:40 +10:00
parent 6fc2fc22ac
commit ac363ff7fa
2 changed files with 20 additions and 10 deletions

View File

@@ -7,7 +7,6 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\PARR.Core\PARR.Core.csproj" />
<ProjectReference Include="..\PARR.DAL\PARR.DAL.csproj" /> <ProjectReference Include="..\PARR.DAL\PARR.DAL.csproj" />
<ProjectReference Include="..\PARR.Domain\PARR.Domain.csproj" /> <ProjectReference Include="..\PARR.Domain\PARR.Domain.csproj" />
<ProjectReference Include="..\PARR.Infrastructure\PARR.Infrastructure.csproj" /> <ProjectReference Include="..\PARR.Infrastructure\PARR.Infrastructure.csproj" />

View File

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