diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_8_5_0/UpdateRelationTypeTable.cs b/src/Umbraco.Core/Migrations/Upgrade/V_8_5_0/UpdateRelationTypeTable.cs
index ed21935488..30174f8d13 100644
--- a/src/Umbraco.Core/Migrations/Upgrade/V_8_5_0/UpdateRelationTypeTable.cs
+++ b/src/Umbraco.Core/Migrations/Upgrade/V_8_5_0/UpdateRelationTypeTable.cs
@@ -11,11 +11,27 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_5_0
public override void Migrate()
{
- Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("parentObjectType").AsGuid().Nullable();
- Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("childObjectType").AsGuid().Nullable();
+ Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("parentObjectType").AsGuid().Nullable().Do();
+ Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("childObjectType").AsGuid().Nullable().Do();
//TODO: We have to update this field to ensure it's not null, we can just copy across the name since that is not nullable
- Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("alias").AsString(100).NotNullable();
+
+ //drop index before we can alter the column
+ if (IndexExists("IX_umbracoRelationType_alias"))
+ Delete
+ .Index("IX_umbracoRelationType_alias")
+ .OnTable(Constants.DatabaseSchema.Tables.RelationType)
+ .Do();
+ //change the column to non nullable
+ Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("alias").AsString(100).NotNullable().Do();
+ //re-create the index
+ Create
+ .Index("IX_umbracoRelationType_alias")
+ .OnTable(Constants.DatabaseSchema.Tables.RelationType)
+ .OnColumn("alias")
+ .Ascending()
+ .WithOptions().Unique().WithOptions().NonClustered()
+ .Do();
}
}
}
diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/RelationTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/RelationTypeRepository.cs
index 075d4aa769..623b55b6f8 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Implement/RelationTypeRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Implement/RelationTypeRepository.cs
@@ -134,7 +134,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistNewItem(IRelationType entity)
{
entity.AddingEntity();
-
+
+ CheckNullObjectTypeValues(entity);
+
var dto = RelationTypeFactory.BuildDto(entity);
var id = Convert.ToInt32(Database.Insert(dto));
@@ -146,7 +148,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
protected override void PersistUpdatedItem(IRelationType entity)
{
entity.UpdatingEntity();
-
+
+ CheckNullObjectTypeValues(entity);
+
var dto = RelationTypeFactory.BuildDto(entity);
Database.Update(dto);
@@ -154,5 +158,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
}
#endregion
+
+ private void CheckNullObjectTypeValues(IRelationType entity)
+ {
+ if (entity.ParentObjectType.HasValue && entity.ParentObjectType == Guid.Empty)
+ entity.ParentObjectType = null;
+ if (entity.ChildObjectType.HasValue && entity.ChildObjectType == Guid.Empty)
+ entity.ChildObjectType = null;
+ }
}
}
diff --git a/src/Umbraco.Core/Services/Implement/RelationService.cs b/src/Umbraco.Core/Services/Implement/RelationService.cs
index cc0a3e23bc..bf1e7bf309 100644
--- a/src/Umbraco.Core/Services/Implement/RelationService.cs
+++ b/src/Umbraco.Core/Services/Implement/RelationService.cs
@@ -326,6 +326,8 @@ namespace Umbraco.Core.Services.Implement
/// An enumerable list of
public IEnumerable GetChildEntitiesFromRelations(IEnumerable relations)
{
+ //TODO: Argh! N+1
+
foreach (var relation in relations)
{
var objectType = ObjectTypes.GetUmbracoObjectType(relation.ChildObjectType);
@@ -340,6 +342,8 @@ namespace Umbraco.Core.Services.Implement
/// An enumerable list of
public IEnumerable GetParentEntitiesFromRelations(IEnumerable relations)
{
+ //TODO: Argh! N+1
+
foreach (var relation in relations)
{
var objectType = ObjectTypes.GetUmbracoObjectType(relation.ParentObjectType);
@@ -354,6 +358,8 @@ namespace Umbraco.Core.Services.Implement
/// An enumerable list of with
public IEnumerable> GetEntitiesFromRelations(IEnumerable relations)
{
+ //TODO: Argh! N+1
+
foreach (var relation in relations)
{
var childObjectType = ObjectTypes.GetUmbracoObjectType(relation.ChildObjectType);
diff --git a/src/Umbraco.Web.UI.Client/src/views/relationtypes/create.html b/src/Umbraco.Web.UI.Client/src/views/relationtypes/create.html
index 67a48e77cd..c854580285 100644
--- a/src/Umbraco.Web.UI.Client/src/views/relationtypes/create.html
+++ b/src/Umbraco.Web.UI.Client/src/views/relationtypes/create.html
@@ -31,8 +31,7 @@
@@ -41,8 +40,7 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/relationtypes/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/relationtypes/edit.controller.js
index 138e3e90e2..f83829dfba 100644
--- a/src/Umbraco.Web.UI.Client/src/views/relationtypes/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/relationtypes/edit.controller.js
@@ -46,7 +46,7 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
});
relationTypeResource.getById($routeParams.id)
- .then(function(data) {
+ .then(function (data) {
bindRelationType(data);
vm.page.loading = false;
});
@@ -54,7 +54,6 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
function bindRelationType(relationType) {
formatDates(relationType.relations);
- getRelationNames(relationType);
// Convert property value to string, since the umb-radiobutton component at the moment only handle string values.
// Sometime later the umb-radiobutton might be able to handle value as boolean.
@@ -70,7 +69,7 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
}
function formatDates(relations) {
- if(relations) {
+ if (relations) {
userService.getCurrentUser().then(function (currentUser) {
angular.forEach(relations, function (relation) {
relation.timestampFormatted = dateHelper.getLocalDate(relation.createDate, currentUser.locale, 'LLL');
@@ -79,41 +78,6 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
}
}
- function getRelationNames(relationType) {
- if (relationType.relations) {
- // can we grab app entity types in one go?
- if (relationType.parentObjectType === relationType.childObjectType) {
- // yep, grab the distinct list of parent and child entities
- var entityIds = _.uniq(_.union(_.pluck(relationType.relations, "parentId"), _.pluck(relationType.relations, "childId")));
- entityResource.getByIds(entityIds, relationType.parentObjectTypeName).then(function (entities) {
- updateRelationNames(relationType, entities);
- });
- } else {
- // nope, grab the parent and child entities individually
- var parentEntityIds = _.uniq(_.pluck(relationType.relations, "parentId"));
- var childEntityIds = _.uniq(_.pluck(relationType.relations, "childId"));
- entityResource.getByIds(parentEntityIds, relationType.parentObjectTypeName).then(function (entities) {
- updateRelationNames(relationType, entities);
- });
- entityResource.getByIds(childEntityIds, relationType.childObjectTypeName).then(function (entities) {
- updateRelationNames(relationType, entities);
- });
- }
- }
- }
-
- function updateRelationNames(relationType, entities) {
- var entitiesById = _.indexBy(entities, "id");
- _.each(relationType.relations, function(relation) {
- if (entitiesById[relation.parentId]) {
- relation.parentName = entitiesById[relation.parentId].name;
- }
- if (entitiesById[relation.childId]) {
- relation.childName = entitiesById[relation.childId].name;
- }
- });
- }
-
function saveRelationType() {
if (formHelper.submitForm({ scope: $scope, statusMessage: "Saving..." })) {
diff --git a/src/Umbraco.Web/Editors/RelationTypeController.cs b/src/Umbraco.Web/Editors/RelationTypeController.cs
index 6fb9108d74..2845a82aa1 100644
--- a/src/Umbraco.Web/Editors/RelationTypeController.cs
+++ b/src/Umbraco.Web/Editors/RelationTypeController.cs
@@ -45,11 +45,8 @@ namespace Umbraco.Web.Editors
throw new HttpResponseException(HttpStatusCode.NotFound);
}
- var relations = Services.RelationService.GetByRelationTypeId(relationType.Id);
-
var display = Mapper.Map(relationType);
- display.Relations = Mapper.MapEnumerable(relations);
-
+
return display;
}
diff --git a/src/Umbraco.Web/Models/ContentEditing/RelationTypeSave.cs b/src/Umbraco.Web/Models/ContentEditing/RelationTypeSave.cs
index e7e8d6d2ba..434cf1de89 100644
--- a/src/Umbraco.Web/Models/ContentEditing/RelationTypeSave.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/RelationTypeSave.cs
@@ -16,12 +16,12 @@ namespace Umbraco.Web.Models.ContentEditing
/// Gets or sets the parent object type ID.
///
[DataMember(Name = "parentObjectType", IsRequired = false)]
- public Guid ParentObjectType { get; set; }
+ public Guid? ParentObjectType { get; set; }
///
/// Gets or sets the child object type ID.
///
[DataMember(Name = "childObjectType", IsRequired = false)]
- public Guid ChildObjectType { get; set; }
+ public Guid? ChildObjectType { get; set; }
}
}
diff --git a/src/Umbraco.Web/Models/Mapping/RelationMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/RelationMapDefinition.cs
index 7f89c78f8a..8407a7421c 100644
--- a/src/Umbraco.Web/Models/Mapping/RelationMapDefinition.cs
+++ b/src/Umbraco.Web/Models/Mapping/RelationMapDefinition.cs
@@ -1,12 +1,23 @@
-using Umbraco.Core;
+using System.Linq;
+using Umbraco.Core;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
+using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Web.Models.Mapping
{
internal class RelationMapDefinition : IMapDefinition
{
+ private readonly IEntityService _entityService;
+ private readonly IRelationService _relationService;
+
+ public RelationMapDefinition(IEntityService entityService, IRelationService relationService)
+ {
+ _entityService = entityService;
+ _relationService = relationService;
+ }
+
public void DefineMaps(UmbracoMapper mapper)
{
mapper.Define((source, context) => new RelationTypeDisplay(), Map);
@@ -15,8 +26,8 @@ namespace Umbraco.Web.Models.Mapping
}
// Umbraco.Code.MapAll -Icon -Trashed -AdditionalData
- // Umbraco.Code.MapAll -Relations -ParentId -Notifications
- private static void Map(IRelationType source, RelationTypeDisplay target, MapperContext context)
+ // Umbraco.Code.MapAll -ParentId -Notifications
+ private void Map(IRelationType source, RelationTypeDisplay target, MapperContext context)
{
target.ChildObjectType = source.ChildObjectType;
target.Id = source.Id;
@@ -28,13 +39,44 @@ namespace Umbraco.Web.Models.Mapping
target.Udi = Udi.Create(Constants.UdiEntityType.RelationType, source.Key);
target.Path = "-1," + source.Id;
- // Set the "friendly" names for the parent and child object types
- target.ParentObjectTypeName = source.ParentObjectType.HasValue ? ObjectTypes.GetUmbracoObjectType(source.ParentObjectType.Value).GetFriendlyName() : string.Empty;
- target.ChildObjectTypeName = source.ChildObjectType.HasValue ? ObjectTypes.GetUmbracoObjectType(source.ChildObjectType.Value).GetFriendlyName() : string.Empty;
+ // Set the "friendly" and entity names for the parent and child object types
+ if (source.ParentObjectType.HasValue)
+ {
+ var objType = ObjectTypes.GetUmbracoObjectType(source.ParentObjectType.Value);
+ target.ParentObjectTypeName = objType.GetFriendlyName();
+ }
+
+ if (source.ChildObjectType.HasValue)
+ {
+ var objType = ObjectTypes.GetUmbracoObjectType(source.ChildObjectType.Value);
+ target.ChildObjectTypeName = objType.GetFriendlyName();
+ }
+
+ // Load the relations
+
+ var relations = _relationService.GetByRelationTypeId(source.Id);
+ var displayRelations = context.MapEnumerable(relations);
+
+ // Load the entities
+ var entities = _relationService.GetEntitiesFromRelations(relations)
+ .ToDictionary(x => (x.Item1.Id, x.Item2.Id), x => x);
+
+ foreach(var r in displayRelations)
+ {
+ var pair = entities[(r.ParentId, r.ChildId)];
+ var parent = pair.Item1;
+ var child = pair.Item2;
+
+ r.ChildName = child.Name;
+ r.ParentName = parent.Name;
+ }
+
+ target.Relations = displayRelations;
+
}
// Umbraco.Code.MapAll -ParentName -ChildName
- private static void Map(IRelation source, RelationDisplay target, MapperContext context)
+ private void Map(IRelation source, RelationDisplay target, MapperContext context)
{
target.ChildId = source.ChildId;
target.Comment = source.Comment;