Refactor BaseItemRepository for ordered DTO materialization

Refactored BaseItemRepository to use a new helper method, MaterializeOrderedDtos, ensuring DTOs are returned in the order of precomputed IDs and improving code reuse. Updated comments to clarify ordering. Cleaned up scenario.json properties and reformatted rebuild-solution.ps1 without changing its logic.
This commit is contained in:
2026-03-07 11:32:56 -05:00
parent 2ba3335ca0
commit e7aa3024cb
3 changed files with 26 additions and 35 deletions
@@ -3,11 +3,8 @@
"operationId": "02bc6448-a69d-4ff4-a0ec-0db07ec3a09a", "operationId": "02bc6448-a69d-4ff4-a0ec-0db07ec3a09a",
"description": "Upgrade solution or project to new version of .NET", "description": "Upgrade solution or project to new version of .NET",
"startTime": "2026-03-05T22:18:32.3921759Z", "startTime": "2026-03-05T22:18:32.3921759Z",
"lastUpdateTime": "2026-03-06T14:43:11.1102232Z", "lastUpdateTime": "2026-03-07T16:26:16.8032461Z",
"stage": "Execution", "stage": "Execution",
"properties": { "properties": {},
"SelectedScenarioStrategy": "BottomUp",
"UpgradeTargetFramework": "net11.0"
},
"folderPath": "" "folderPath": ""
} }
@@ -424,17 +424,13 @@ public sealed class BaseItemRepository
return result; return result;
} }
// Load full entities with navigations // Load full entities with navigations and preserve the precomputed id order.
var dbQueryWithNavs = ApplyNavigations(context.BaseItems.Where(e => pagedIds.Contains(e.Id)), filter); var dbQueryWithNavs = ApplyNavigations(context.BaseItems.Where(e => pagedIds.Contains(e.Id)), filter);
var items = await dbQueryWithNavs var items = await dbQueryWithNavs
.ToListAsync(cancellationToken) .ToListAsync(cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
result.Items = items result.Items = MaterializeOrderedDtos(items, pagedIds, filter.SkipDeserialization);
.Where(e => e is not null)
.Select(w => DeserializeBaseItem(w, filter.SkipDeserialization))
.Where(dto => dto is not null)
.ToArray()!;
result.StartIndex = filter.StartIndex ?? 0; result.StartIndex = filter.StartIndex ?? 0;
return result; return result;
} }
@@ -497,24 +493,15 @@ public sealed class BaseItemRepository
.ToListAsync(cancellationToken) .ToListAsync(cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
var itemsById = items return MaterializeOrderedDtos(items, pagedIds, filter.SkipDeserialization);
.Select(w => DeserializeBaseItem(w, filter.SkipDeserialization))
.Where(dto => dto is not null)
.ToDictionary(i => i!.Id);
return pagedIds.Where(itemsById.ContainsKey).Select(id => itemsById[id]).ToArray()!;
} }
// Load full entities with navigations // Load full entities with navigations and preserve the precomputed id order.
var results = await ApplyNavigations(context.BaseItems.Where(e => pagedIds.Contains(e.Id)), filter) var results = await ApplyNavigations(context.BaseItems.Where(e => pagedIds.Contains(e.Id)), filter)
.ToListAsync(cancellationToken) .ToListAsync(cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
return results return MaterializeOrderedDtos(results, pagedIds, filter.SkipDeserialization);
.Where(e => e is not null)
.Select(w => DeserializeBaseItem(w, filter.SkipDeserialization))
.Where(dto => dto is not null)
.ToArray()!;
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -601,16 +588,12 @@ public sealed class BaseItemRepository
return Array.Empty<BaseItem>(); return Array.Empty<BaseItem>();
} }
// Load full entities with navigations // Load full entities with navigations and preserve the precomputed id order.
var results = await ApplyNavigations(context.BaseItems.Where(e => pagedIds.Contains(e.Id)), filter) var results = await ApplyNavigations(context.BaseItems.Where(e => pagedIds.Contains(e.Id)), filter)
.ToListAsync(cancellationToken) .ToListAsync(cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
return results return MaterializeOrderedDtos(results, pagedIds, filter.SkipDeserialization);
.Where(e => e is not null)
.Select(w => DeserializeBaseItem(w, filter.SkipDeserialization))
.Where(dto => dto is not null)
.ToArray()!;
} }
else else
{ {
@@ -655,16 +638,12 @@ public sealed class BaseItemRepository
return Array.Empty<BaseItem>(); return Array.Empty<BaseItem>();
} }
// Load full entities with navigations // Load full entities with navigations and preserve the precomputed id order.
var results = await ApplyNavigations(context.BaseItems.Where(e => pagedIds.Contains(e.Id)), filter) var results = await ApplyNavigations(context.BaseItems.Where(e => pagedIds.Contains(e.Id)), filter)
.ToListAsync(cancellationToken) .ToListAsync(cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
return results return MaterializeOrderedDtos(results, pagedIds, filter.SkipDeserialization);
.Where(e => e is not null)
.Select(w => DeserializeBaseItem(w, filter.SkipDeserialization))
.Where(dto => dto is not null)
.ToArray()!;
} }
} }
} }
@@ -840,6 +819,21 @@ public sealed class BaseItemRepository
return paged.ToList(); return paged.ToList();
} }
private IReadOnlyList<BaseItemDto> MaterializeOrderedDtos(IReadOnlyList<BaseItemEntity> entities, IReadOnlyList<Guid> orderedIds, bool skipDeserialization)
{
if (orderedIds.Count == 0 || entities.Count == 0)
{
return Array.Empty<BaseItemDto>();
}
var itemsById = entities
.Select(w => DeserializeBaseItem(w, skipDeserialization))
.Where(dto => dto is not null)
.ToDictionary(i => i!.Id);
return orderedIds.Where(itemsById.ContainsKey).Select(id => itemsById[id]).ToArray()!;
}
private IQueryable<BaseItemEntity> ApplyQueryPaging(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter) private IQueryable<BaseItemEntity> ApplyQueryPaging(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
{ {
if (filter.StartIndex.HasValue && filter.StartIndex.Value > 0) if (filter.StartIndex.HasValue && filter.StartIndex.Value > 0)