diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByChildRelationController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByChildRelationController.cs
index 8a71ea700c..b93fe47ec6 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByChildRelationController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByChildRelationController.cs
@@ -6,6 +6,8 @@ using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
using Umbraco.Cms.Api.Management.ViewModels.Relation;
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Extensions;
namespace Umbraco.Cms.Api.Management.Controllers.Relation;
@@ -24,31 +26,25 @@ public class ByChildRelationController : RelationControllerBase
_relationPresentationFactory = relationPresentationFactory;
}
- [HttpGet("child-relation/{childId:int}")]
+ ///
+ /// Gets a paged list of relations by the unique relation child keys.
+ ///
+ ///
+ /// Use case: When you wanna restore a deleted item, this is used to find the old location
+ ///
+ [HttpGet("child-relation/{childId:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
- public async Task> ByChild(int childId, int skip = 0, int take = 100, string? relationTypeAlias = "")
+ public async Task ByChild(Guid childId, int skip = 0, int take = 100, string? relationTypeAlias = "")
{
- IRelation[] relations = _relationService.GetByChildId(childId).ToArray();
- RelationResponseModel[] result = Array.Empty();
+ PagedModel relationsAttempt = await _relationService.GetPagedByChildKeyAsync(childId, skip, take, relationTypeAlias);
- if (relations.Any())
- {
- if (string.IsNullOrWhiteSpace(relationTypeAlias) == false)
- {
- result = _relationPresentationFactory.CreateMultiple(relations.Where(x =>
- x.RelationType.Alias.InvariantEquals(relationTypeAlias))).ToArray();
- }
- else
- {
- result = _relationPresentationFactory.CreateMultiple(relations).ToArray();
- }
- }
+ IEnumerable mappedRelations = relationsAttempt.Items.Select(_relationPresentationFactory.Create);
- return await Task.FromResult(new PagedViewModel
+ return await Task.FromResult(Ok(new PagedViewModel
{
- Total = result.Length,
- Items = result.Skip(skip).Take(take),
- });
+ Total = relationsAttempt.Total,
+ Items = mappedRelations,
+ }));
}
}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByIdRelationController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByIdRelationController.cs
deleted file mode 100644
index 1ad45a5912..0000000000
--- a/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByIdRelationController.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Asp.Versioning;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Umbraco.Cms.Core.Models;
-using Umbraco.Cms.Core.Services;
-using Umbraco.Cms.Api.Management.Factories;
-using Umbraco.Cms.Api.Management.ViewModels.Relation;
-
-namespace Umbraco.Cms.Api.Management.Controllers.Relation;
-
-[ApiVersion("1.0")]
-public class ByIdRelationController : RelationControllerBase
-{
- private readonly IRelationService _relationService;
- private readonly IRelationPresentationFactory _relationPresentationFactory;
-
- public ByIdRelationController(IRelationService relationService, IRelationPresentationFactory relationPresentationFactory)
- {
- _relationService = relationService;
- _relationPresentationFactory = relationPresentationFactory;
- }
-
- [HttpGet("{id:int}")]
- [MapToApiVersion("1.0")]
- [ProducesResponseType(typeof(RelationResponseModel), StatusCodes.Status200OK)]
- [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
- public async Task ById(int id)
- {
- IRelation? relation = _relationService.GetById(id);
- if (relation is null)
- {
- return RelationNotFound();
- }
-
- return await Task.FromResult(Ok(_relationPresentationFactory.Create(relation)));
- }
-}
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByRelationTypeKeyRelationController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByRelationTypeKeyRelationController.cs
index aaca170877..f0d904ec20 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByRelationTypeKeyRelationController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Relation/ByRelationTypeKeyRelationController.cs
@@ -23,13 +23,19 @@ public class ByRelationTypeKeyRelationController : RelationControllerBase
_relationPresentationFactory = relationPresentationFactory;
}
+ ///
+ /// Gets a paged list of relations by the unique relation key.
+ ///
+ ///
+ /// Use case: On a relation type page you can see all created relations of this type.
+ ///
[HttpGet("type/{id:guid}")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(PagedViewModel), StatusCodes.Status404NotFound)]
public async Task ByRelationTypeKey(Guid id, int skip = 0, int take = 100)
{
- Attempt, RelationOperationStatus> relationsAttempt = await _relationService.GetPagedByRelationTypeKey(id, skip, take);
+ Attempt, RelationOperationStatus> relationsAttempt = await _relationService.GetPagedByRelationTypeKeyAsync(id, skip, take);
if (relationsAttempt.Success is false)
{
diff --git a/src/Umbraco.Cms.Api.Management/DependencyInjection/TrackedReferencesBuilderExtensions.cs b/src/Umbraco.Cms.Api.Management/DependencyInjection/TrackedReferencesBuilderExtensions.cs
index 9bb387d2f4..d94d0649f6 100644
--- a/src/Umbraco.Cms.Api.Management/DependencyInjection/TrackedReferencesBuilderExtensions.cs
+++ b/src/Umbraco.Cms.Api.Management/DependencyInjection/TrackedReferencesBuilderExtensions.cs
@@ -1,6 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Management.Factories;
-using Umbraco.Cms.Api.Management.Mapping.Relation;
using Umbraco.Cms.Api.Management.Mapping.TrackedReferences;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Mapping;
@@ -16,8 +15,7 @@ internal static class TrackedReferencesBuilderExtensions
builder.WithCollectionBuilder()
.Add()
- .Add()
- .Add();
+ .Add();
return builder;
}
diff --git a/src/Umbraco.Cms.Api.Management/Factories/RelationPresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/RelationPresentationFactory.cs
index 52d86d2102..4a8e1ad3ef 100644
--- a/src/Umbraco.Cms.Api.Management/Factories/RelationPresentationFactory.cs
+++ b/src/Umbraco.Cms.Api.Management/Factories/RelationPresentationFactory.cs
@@ -9,17 +9,26 @@ namespace Umbraco.Cms.Api.Management.Factories;
public class RelationPresentationFactory : IRelationPresentationFactory
{
private readonly IRelationService _relationService;
- private readonly IUmbracoMapper _umbracoMapper;
+ private readonly IEntityService _entityService;
- public RelationPresentationFactory(IRelationService relationService, IUmbracoMapper umbracoMapper)
+ public RelationPresentationFactory(IRelationService relationService, IEntityService entityService)
{
_relationService = relationService;
- _umbracoMapper = umbracoMapper;
+ _entityService = entityService;
}
public RelationResponseModel Create(IRelation relation)
{
- RelationResponseModel relationResponseModel = _umbracoMapper.Map(relation)!;
+ var child = _entityService.Get(relation.ChildId)!;
+ var parent = _entityService.Get(relation.ParentId)!;
+
+ RelationResponseModel relationResponseModel = new RelationResponseModel()
+ {
+ ChildId = child.Key,
+ Comment = relation.Comment,
+ CreateDate = relation.CreateDate,
+ ParentId = parent.Key,
+ };
Tuple? entities = _relationService.GetEntitiesFromRelation(relation);
if (entities is not null)
diff --git a/src/Umbraco.Cms.Api.Management/Mapping/Relation/RelationViewModelsMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/Relation/RelationViewModelsMapDefinition.cs
deleted file mode 100644
index d3137bfcd6..0000000000
--- a/src/Umbraco.Cms.Api.Management/Mapping/Relation/RelationViewModelsMapDefinition.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using Umbraco.Cms.Core.Mapping;
-using Umbraco.Cms.Core.Models;
-using Umbraco.Cms.Api.Management.ViewModels.Relation;
-
-namespace Umbraco.Cms.Api.Management.Mapping.Relation;
-
-public class RelationViewModelsMapDefinition : IMapDefinition
-{
- public void DefineMaps(IUmbracoMapper mapper)
- {
- mapper.Define((source, context) => new RelationResponseModel(), Map);
- }
-
- // Umbraco.Code.MapAll -ParentName -ChildName
- private void Map(IRelation source, RelationResponseModel target, MapperContext context)
- {
- target.ChildId = source.ChildId;
- target.Comment = source.Comment;
- target.CreateDate = source.CreateDate;
- target.ParentId = source.ParentId;
- }
-}
diff --git a/src/Umbraco.Cms.Api.Management/OpenApi.json b/src/Umbraco.Cms.Api.Management/OpenApi.json
index 2f7186d500..06c7657cbd 100644
--- a/src/Umbraco.Cms.Api.Management/OpenApi.json
+++ b/src/Umbraco.Cms.Api.Management/OpenApi.json
@@ -11407,84 +11407,6 @@
]
}
},
- "/umbraco/management/api/v1/relation/{id}": {
- "get": {
- "tags": [
- "Relation"
- ],
- "operationId": "GetRelationById",
- "parameters": [
- {
- "name": "id",
- "in": "path",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "Success",
- "content": {
- "application/json": {
- "schema": {
- "oneOf": [
- {
- "$ref": "#/components/schemas/RelationResponseModel"
- }
- ]
- }
- },
- "text/json": {
- "schema": {
- "oneOf": [
- {
- "$ref": "#/components/schemas/RelationResponseModel"
- }
- ]
- }
- },
- "text/plain": {
- "schema": {
- "oneOf": [
- {
- "$ref": "#/components/schemas/RelationResponseModel"
- }
- ]
- }
- }
- }
- },
- "404": {
- "description": "Not Found",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- },
- "text/plain": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- }
- }
- }
- },
- "security": [
- {
- "Backoffice User": [ ]
- }
- ]
- }
- },
"/umbraco/management/api/v1/relation/child-relation/{childId}": {
"get": {
"tags": [
@@ -11497,8 +11419,8 @@
"in": "path",
"required": true,
"schema": {
- "type": "integer",
- "format": "int32"
+ "type": "string",
+ "format": "uuid"
}
},
{
@@ -21091,16 +21013,16 @@
"type": "object",
"properties": {
"parentId": {
- "type": "integer",
- "format": "int32"
+ "type": "string",
+ "format": "uuid"
},
"parentName": {
"type": "string",
"nullable": true
},
"childId": {
- "type": "integer",
- "format": "int32"
+ "type": "string",
+ "format": "uuid"
},
"childName": {
"type": "string",
diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/Relation/RelationResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/Relation/RelationResponseModel.cs
index 88291bfe02..4aefe4891d 100644
--- a/src/Umbraco.Cms.Api.Management/ViewModels/Relation/RelationResponseModel.cs
+++ b/src/Umbraco.Cms.Api.Management/ViewModels/Relation/RelationResponseModel.cs
@@ -9,7 +9,7 @@ public class RelationResponseModel
/// Gets or sets the Parent Id of the Relation (Source).
///
[ReadOnly(true)]
- public int ParentId { get; set; }
+ public Guid ParentId { get; set; }
///
/// Gets or sets the Parent Name of the relation (Source).
@@ -21,7 +21,7 @@ public class RelationResponseModel
/// Gets or sets the Child Id of the Relation (Destination).
///
[ReadOnly(true)]
- public int ChildId { get; set; }
+ public Guid ChildId { get; set; }
///
/// Gets or sets the Child Name of the relation (Destination).
diff --git a/src/Umbraco.Core/Persistence/Repositories/IRelationRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IRelationRepository.cs
index 8077a80dc1..6a7202feaa 100644
--- a/src/Umbraco.Core/Persistence/Repositories/IRelationRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/IRelationRepository.cs
@@ -2,6 +2,7 @@ using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Persistence.Querying;
using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Core.Persistence.Repositories;
@@ -33,4 +34,5 @@ public interface IRelationRepository : IReadWriteQueryRepository
IEnumerable GetPagedParentEntitiesByChildId(int childId, long pageIndex, int pageSize, out long totalRecords, params Guid[] entityTypes);
IEnumerable GetPagedChildEntitiesByParentId(int parentId, long pageIndex, int pageSize, out long totalRecords, params Guid[] entityTypes);
+ Task> GetPagedByChildKeyAsync(Guid childKey, int skip, int take, string? relationTypeAlias);
}
diff --git a/src/Umbraco.Core/Services/IRelationService.cs b/src/Umbraco.Core/Services/IRelationService.cs
index 3cc9ca2638..bd823b08c5 100644
--- a/src/Umbraco.Core/Services/IRelationService.cs
+++ b/src/Umbraco.Core/Services/IRelationService.cs
@@ -181,7 +181,7 @@ public interface IRelationService : IService
///
///
///
- Task, RelationOperationStatus>> GetPagedByRelationTypeKey(Guid key, int skip, int take, Ordering? ordering = null);
+ Task, RelationOperationStatus>> GetPagedByRelationTypeKeyAsync(Guid key, int skip, int take, Ordering? ordering = null);
///
/// Gets the Child object from a Relation as an
@@ -392,4 +392,6 @@ public interface IRelationService : IService
///
/// All of the allowed .
IEnumerable GetAllowedObjectTypes();
+
+ Task> GetPagedByChildKeyAsync(Guid childKey, int skip, int take, string? relationTypeAlias);
}
diff --git a/src/Umbraco.Core/Services/RelationService.cs b/src/Umbraco.Core/Services/RelationService.cs
index 52dad36f35..9d5a392834 100644
--- a/src/Umbraco.Core/Services/RelationService.cs
+++ b/src/Umbraco.Core/Services/RelationService.cs
@@ -273,7 +273,15 @@ public class RelationService : RepositoryService, IRelationService
}
}
- public async Task, RelationOperationStatus>> GetPagedByRelationTypeKey(Guid key, int skip, int take, Ordering? ordering = null)
+ public async Task> GetPagedByChildKeyAsync(Guid childKey, int skip, int take, string? relationTypeAlias)
+ {
+ using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
+ {
+ return await _relationRepository.GetPagedByChildKeyAsync(childKey, skip, take, relationTypeAlias);
+ }
+ }
+
+ public async Task, RelationOperationStatus>> GetPagedByRelationTypeKeyAsync(Guid key, int skip, int take, Ordering? ordering = null)
{
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
{
diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/RelationRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/RelationRepository.cs
index 9431633993..a38bf4547f 100644
--- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/RelationRepository.cs
+++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/RelationRepository.cs
@@ -7,6 +7,7 @@ using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Persistence.Querying;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Core.Services.OperationStatus;
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
using Umbraco.Cms.Infrastructure.Persistence.Factories;
using Umbraco.Cms.Infrastructure.Persistence.Querying;
@@ -38,6 +39,27 @@ internal class RelationRepository : EntityRepositoryBase, IRelat
public IEnumerable GetPagedChildEntitiesByParentId(int parentId, long pageIndex, int pageSize, out long totalRecords, params Guid[] entityTypes)
=> GetPagedChildEntitiesByParentId(parentId, pageIndex, pageSize, out totalRecords, new int[0], entityTypes);
+ public Task> GetPagedByChildKeyAsync(Guid childKey, int skip, int take, string? relationTypeAlias)
+ {
+ Sql sql = GetBaseQuery(false);
+
+ if (string.IsNullOrEmpty(relationTypeAlias) is false)
+ {
+
+ sql = sql.InnerJoin().On(umbracoRelation => umbracoRelation.RelationType, rt => rt.Id)
+ .Where(rt => rt.Alias == relationTypeAlias);
+ }
+ sql = sql.Where(n => n.UniqueId == childKey, "uchild"); // "uchild" comes from the base query
+
+
+ RelationDto[] pagedResult =
+ Database.SkipTake(skip, take, sql).ToArray();
+ var totalRecords = Database.Count(sql);
+
+ return Task.FromResult(new PagedModel(totalRecords, DtosToEntities(pagedResult)));
+
+ }
+
public void Save(IEnumerable relations)
{
foreach (IGrouping hasIdentityGroup in relations.GroupBy(r => r.HasIdentity))