Allows relation types to not have specific object types, updates IRelation to return the actual object types for the ID references, now relations can be more flexible without being strangely tied to specific object types based on the relation type.
This commit is contained in:
@@ -26,10 +26,11 @@ namespace Umbraco.Core.Compose
|
||||
|
||||
if (relationType == null)
|
||||
{
|
||||
relationType = new RelationType(Constants.ObjectTypes.Document,
|
||||
relationType = new RelationType(Constants.Conventions.RelationTypes.RelateDocumentOnCopyAlias,
|
||||
Constants.Conventions.RelationTypes.RelateDocumentOnCopyName,
|
||||
true,
|
||||
Constants.ObjectTypes.Document,
|
||||
Constants.Conventions.RelationTypes.RelateDocumentOnCopyAlias,
|
||||
Constants.Conventions.RelationTypes.RelateDocumentOnCopyName) { IsBidirectional = true };
|
||||
Constants.ObjectTypes.Document);
|
||||
|
||||
relationService.Save(relationType);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Umbraco.Core.Compose
|
||||
var documentObjectType = Constants.ObjectTypes.Document;
|
||||
const string relationTypeName = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteName;
|
||||
|
||||
relationType = new RelationType(documentObjectType, documentObjectType, relationTypeAlias, relationTypeName);
|
||||
relationType = new RelationType(relationTypeName, relationTypeAlias, false, documentObjectType, documentObjectType);
|
||||
relationService.Save(relationType);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace Umbraco.Core.Compose
|
||||
{
|
||||
var documentObjectType = Constants.ObjectTypes.Document;
|
||||
const string relationTypeName = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName;
|
||||
relationType = new RelationType(documentObjectType, documentObjectType, relationTypeAlias, relationTypeName);
|
||||
relationType = new RelationType(relationTypeName, relationTypeAlias, false, documentObjectType, documentObjectType);
|
||||
relationService.Save(relationType);
|
||||
}
|
||||
foreach (var item in e.MoveInfoCollection)
|
||||
|
||||
@@ -325,7 +325,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
relationType.UniqueId = (relationType.Alias + "____" + relationType.Name).ToGuid();
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.RelationType, "id", false, relationType);
|
||||
|
||||
relationType = new RelationTypeDto { Id = 4, Alias = Constants.Conventions.RelationTypes.RelatedDocumentAlias, ChildObjectType = Constants.ObjectTypes.Document, ParentObjectType = Constants.ObjectTypes.Document, Dual = false, Name = Constants.Conventions.RelationTypes.RelatedDocumentName };
|
||||
relationType = new RelationTypeDto { Id = 5, Alias = Constants.Conventions.RelationTypes.RelatedDocumentAlias, ChildObjectType = Constants.ObjectTypes.Document, ParentObjectType = Constants.ObjectTypes.Document, Dual = false, Name = Constants.Conventions.RelationTypes.RelatedDocumentName };
|
||||
relationType.UniqueId = (relationType.Alias + "____" + relationType.Name).ToGuid();
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.RelationType, "id", false, relationType);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Umbraco.Core.Migrations.Upgrade.Common;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_1;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_1_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_5_0;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade
|
||||
{
|
||||
@@ -182,6 +183,9 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
To<RenameUserLoginDtoDateIndex>("{0372A42B-DECF-498D-B4D1-6379E907EB94}");
|
||||
To<FixContentNuCascade>("{5B1E0D93-F5A3-449B-84BA-65366B84E2D4}");
|
||||
|
||||
// to 8.5.0...
|
||||
To<UpdateRelationTypeTable>("{4759A294-9860-46BC-99F9-B4C975CAE580}");
|
||||
|
||||
//FINAL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_5_0
|
||||
{
|
||||
public class UpdateRelationTypeTable : MigrationBase
|
||||
{
|
||||
public UpdateRelationTypeTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
|
||||
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("parentObjectType").AsGuid().Nullable();
|
||||
Alter.Table(Constants.DatabaseSchema.Tables.RelationType).AlterColumn("childObjectType").AsGuid().Nullable();
|
||||
|
||||
//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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Runtime.Serialization;
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
@@ -11,12 +12,18 @@ namespace Umbraco.Core.Models
|
||||
[DataMember]
|
||||
int ParentId { get; set; }
|
||||
|
||||
[DataMember]
|
||||
Guid ParentObjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Child Id of the Relation (Destination)
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
int ChildId { get; set; }
|
||||
|
||||
[DataMember]
|
||||
Guid ChildObjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="RelationType"/> for the Relation
|
||||
/// </summary>
|
||||
|
||||
@@ -29,13 +29,13 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
|
||||
[DataMember]
|
||||
Guid ParentObjectType { get; set; }
|
||||
Guid? ParentObjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Childs object type id
|
||||
/// </summary>
|
||||
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
|
||||
[DataMember]
|
||||
Guid ChildObjectType { get; set; }
|
||||
Guid? ChildObjectType { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,37 @@ namespace Umbraco.Core.Models
|
||||
private IRelationType _relationType;
|
||||
private string _comment;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for constructing the entity to be created
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
/// <param name="childId"></param>
|
||||
/// <param name="parentObjectType"></param>
|
||||
/// <param name="childObjectType"></param>
|
||||
/// <param name="relationType"></param>
|
||||
public Relation(int parentId, int childId, IRelationType relationType)
|
||||
{
|
||||
_parentId = parentId;
|
||||
_childId = childId;
|
||||
_relationType = relationType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for reconstructing the entity from the data source
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
/// <param name="childId"></param>
|
||||
/// <param name="parentObjectType"></param>
|
||||
/// <param name="childObjectType"></param>
|
||||
/// <param name="relationType"></param>
|
||||
public Relation(int parentId, int childId, Guid parentObjectType, Guid childObjectType, IRelationType relationType)
|
||||
{
|
||||
_parentId = parentId;
|
||||
_childId = childId;
|
||||
_relationType = relationType;
|
||||
ParentObjectType = parentObjectType;
|
||||
ChildObjectType = childObjectType;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -35,6 +60,9 @@ namespace Umbraco.Core.Models
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _parentId, nameof(ParentId));
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public Guid ParentObjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Child Id of the Relation (Destination)
|
||||
/// </summary>
|
||||
@@ -45,6 +73,9 @@ namespace Umbraco.Core.Models
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _childId, nameof(ChildId));
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public Guid ChildObjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="RelationType"/> for the Relation
|
||||
/// </summary>
|
||||
|
||||
@@ -15,24 +15,26 @@ namespace Umbraco.Core.Models
|
||||
private string _name;
|
||||
private string _alias;
|
||||
private bool _isBidrectional;
|
||||
private Guid _parentObjectType;
|
||||
private Guid _childObjectType;
|
||||
private Guid? _parentObjectType;
|
||||
private Guid? _childObjectType;
|
||||
|
||||
public RelationType(Guid childObjectType, Guid parentObjectType, string alias)
|
||||
//TODO: Should we put back the broken ctors with obsolete attributes?
|
||||
|
||||
public RelationType(string alias, string name)
|
||||
: this(name, alias, false, null, null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(alias)) throw new ArgumentNullOrEmptyException(nameof(alias));
|
||||
_childObjectType = childObjectType;
|
||||
_parentObjectType = parentObjectType;
|
||||
}
|
||||
|
||||
public RelationType(string name, string alias, bool isBidrectional, Guid? parentObjectType, Guid? childObjectType)
|
||||
{
|
||||
_name = name;
|
||||
_alias = alias;
|
||||
Name = _alias;
|
||||
_isBidrectional = isBidrectional;
|
||||
_parentObjectType = parentObjectType;
|
||||
_childObjectType = childObjectType;
|
||||
}
|
||||
|
||||
public RelationType(Guid childObjectType, Guid parentObjectType, string alias, string name)
|
||||
: this(childObjectType, parentObjectType, alias)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
|
||||
Name = name;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name of the RelationType
|
||||
@@ -69,7 +71,7 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
|
||||
[DataMember]
|
||||
public Guid ParentObjectType
|
||||
public Guid? ParentObjectType
|
||||
{
|
||||
get => _parentObjectType;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _parentObjectType, nameof(ParentObjectType));
|
||||
@@ -80,7 +82,7 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
|
||||
[DataMember]
|
||||
public Guid ChildObjectType
|
||||
public Guid? ChildObjectType
|
||||
{
|
||||
get => _childObjectType;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _childObjectType, nameof(ChildObjectType));
|
||||
|
||||
@@ -34,5 +34,13 @@ namespace Umbraco.Core.Persistence.Dtos
|
||||
[Column("comment")]
|
||||
[Length(1000)]
|
||||
public string Comment { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Column("parentObjectType")]
|
||||
public Guid ParentObjectType { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Column("childObjectType")]
|
||||
public Guid ChildObjectType { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Persistence.Dtos
|
||||
[ExplicitColumns]
|
||||
internal class RelationTypeDto
|
||||
{
|
||||
public const int NodeIdSeed = 4;
|
||||
public const int NodeIdSeed = 10;
|
||||
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn(IdentitySeed = NodeIdSeed)]
|
||||
@@ -23,17 +23,20 @@ namespace Umbraco.Core.Persistence.Dtos
|
||||
public bool Dual { get; set; }
|
||||
|
||||
[Column("parentObjectType")]
|
||||
public Guid ParentObjectType { get; set; }
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public Guid? ParentObjectType { get; set; }
|
||||
|
||||
[Column("childObjectType")]
|
||||
public Guid ChildObjectType { get; set; }
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public Guid? ChildObjectType { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRelationType_name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("alias")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
[NullSetting(NullSetting = NullSettings.NotNull)]
|
||||
[Length(100)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRelationType_alias")]
|
||||
public string Alias { get; set; }
|
||||
|
||||
@@ -3,20 +3,11 @@ using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class RelationFactory
|
||||
internal static class RelationFactory
|
||||
{
|
||||
private readonly IRelationType _relationType;
|
||||
|
||||
public RelationFactory(IRelationType relationType)
|
||||
public static IRelation BuildEntity(RelationDto dto, IRelationType relationType)
|
||||
{
|
||||
_relationType = relationType;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<Relation,RelationDto>
|
||||
|
||||
public IRelation BuildEntity(RelationDto dto)
|
||||
{
|
||||
var entity = new Relation(dto.ParentId, dto.ChildId, _relationType);
|
||||
var entity = new Relation(dto.ParentId, dto.ChildId, dto.ParentObjectType, dto.ChildObjectType, relationType);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -37,7 +28,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
}
|
||||
}
|
||||
|
||||
public RelationDto BuildDto(IRelation entity)
|
||||
public static RelationDto BuildDto(IRelation entity)
|
||||
{
|
||||
var dto = new RelationDto
|
||||
{
|
||||
@@ -54,6 +45,5 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
return dto;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
public static IRelationType BuildEntity(RelationTypeDto dto)
|
||||
{
|
||||
var entity = new RelationType(dto.ChildObjectType, dto.ParentObjectType, dto.Alias);
|
||||
var entity = new RelationType(dto.Name, dto.Alias, dto.Dual, dto.ChildObjectType, dto.ParentObjectType);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -17,8 +17,6 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
entity.Id = dto.Id;
|
||||
entity.Key = dto.UniqueId;
|
||||
entity.IsBidirectional = dto.Dual;
|
||||
entity.Name = dto.Name;
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
entity.ResetDirtyProperties(false);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Core.Models;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
|
||||
@@ -11,6 +11,7 @@ using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Scoping;
|
||||
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
@@ -40,10 +41,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
var relationType = _relationTypeRepository.Get(dto.RelationType);
|
||||
if (relationType == null)
|
||||
throw new Exception(string.Format("RelationType with Id: {0} doesn't exist", dto.RelationType));
|
||||
throw new InvalidOperationException(string.Format("RelationType with Id: {0} doesn't exist", dto.RelationType));
|
||||
|
||||
var factory = new RelationFactory(relationType);
|
||||
return DtoToEntity(dto, factory);
|
||||
return DtoToEntity(dto, relationType);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IRelation> PerformGetAll(params int[] ids)
|
||||
@@ -68,26 +68,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
private IEnumerable<IRelation> DtosToEntities(IEnumerable<RelationDto> dtos)
|
||||
{
|
||||
// in most cases, the relation type will be the same for all of them,
|
||||
// plus we've ordered the relations by type, so try to allocate as few
|
||||
// factories as possible - bearing in mind that relation types are cached
|
||||
RelationFactory factory = null;
|
||||
var relationTypeId = -1;
|
||||
//NOTE: This is N+1, BUT ALL relation types are cached so shouldn't matter
|
||||
|
||||
return dtos.Select(x =>
|
||||
{
|
||||
if (relationTypeId != x.RelationType)
|
||||
factory = new RelationFactory(_relationTypeRepository.Get(relationTypeId = x.RelationType));
|
||||
return DtoToEntity(x, factory);
|
||||
}).ToList();
|
||||
return dtos.Select(x => DtoToEntity(x, _relationTypeRepository.Get(x.RelationType))).ToList();
|
||||
}
|
||||
|
||||
private static IRelation DtoToEntity(RelationDto dto, RelationFactory factory)
|
||||
private static IRelation DtoToEntity(RelationDto dto, IRelationType relationType)
|
||||
{
|
||||
var entity = factory.BuildEntity(dto);
|
||||
var entity = RelationFactory.BuildEntity(dto, relationType);
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
((BeingDirtyBase)entity).ResetDirtyProperties(false);
|
||||
entity.ResetDirtyProperties(false);
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -98,14 +89,18 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
protected override Sql<ISqlContext> GetBaseQuery(bool isCount)
|
||||
{
|
||||
var sql = Sql();
|
||||
if (isCount)
|
||||
{
|
||||
return Sql().SelectCount().From<RelationDto>();
|
||||
}
|
||||
|
||||
sql = isCount
|
||||
? sql.SelectCount()
|
||||
: sql.Select<RelationDto>();
|
||||
var sql = Sql().Select<RelationDto>()
|
||||
.AndSelect<NodeDto>("uchild", x => Alias(x.NodeObjectType, "childObjectType"))
|
||||
.AndSelect<NodeDto>("uparent", x => Alias(x.NodeObjectType, "parentObjectType"))
|
||||
.From<RelationDto>()
|
||||
.InnerJoin<NodeDto>("uchild").On<RelationDto, NodeDto>((rel, node) => rel.ChildId == node.NodeId, aliasRight: "uchild")
|
||||
.InnerJoin<NodeDto>("uparent").On<RelationDto, NodeDto>((rel, node) => rel.ParentId == node.NodeId, aliasRight: "uparent");
|
||||
|
||||
sql
|
||||
.From<RelationDto>();
|
||||
|
||||
return sql;
|
||||
}
|
||||
@@ -137,11 +132,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
entity.AddingEntity();
|
||||
|
||||
var factory = new RelationFactory(entity.RelationType);
|
||||
var dto = factory.BuildDto(entity);
|
||||
var dto = RelationFactory.BuildDto(entity);
|
||||
|
||||
var id = Convert.ToInt32(Database.Insert(dto));
|
||||
|
||||
entity.Id = id;
|
||||
PopulateObjectTypes(entity);
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
@@ -150,10 +146,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
{
|
||||
entity.UpdatingEntity();
|
||||
|
||||
var factory = new RelationFactory(entity.RelationType);
|
||||
var dto = factory.BuildDto(entity);
|
||||
var dto = RelationFactory.BuildDto(entity);
|
||||
Database.Update(dto);
|
||||
|
||||
PopulateObjectTypes(entity);
|
||||
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
@@ -173,5 +170,13 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
|
||||
Database.Execute(Sql().Delete<RelationDto>().WhereIn<RelationDto>(x => x.Id, subQuery));
|
||||
}
|
||||
|
||||
private void PopulateObjectTypes(IRelation entity)
|
||||
{
|
||||
var nodes = Database.Fetch<NodeDto>(Sql().Select<NodeDto>().From<NodeDto>().Where<NodeDto>(x => x.NodeId == entity.ChildId || x.NodeId == entity.ParentId))
|
||||
.ToDictionary(x => x.NodeId, x => x.NodeObjectType);
|
||||
entity.ParentObjectType = nodes[entity.ParentId].Value;
|
||||
entity.ChildObjectType = nodes[entity.ChildId].Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
public IUmbracoEntity GetChildEntityFromRelation(IRelation relation)
|
||||
{
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.ChildObjectType);
|
||||
return _entityService.Get(relation.ChildId, objectType);
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
public IUmbracoEntity GetParentEntityFromRelation(IRelation relation)
|
||||
{
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.ParentObjectType);
|
||||
return _entityService.Get(relation.ParentId, objectType);
|
||||
}
|
||||
|
||||
@@ -310,8 +310,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
/// <returns>Returns a Tuple with Parent (item1) and Child (item2)</returns>
|
||||
public Tuple<IUmbracoEntity, IUmbracoEntity> GetEntitiesFromRelation(IRelation relation)
|
||||
{
|
||||
var childObjectType = ObjectTypes.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
|
||||
var parentObjectType = ObjectTypes.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
|
||||
var childObjectType = ObjectTypes.GetUmbracoObjectType(relation.ChildObjectType);
|
||||
var parentObjectType = ObjectTypes.GetUmbracoObjectType(relation.ParentObjectType);
|
||||
|
||||
var child = _entityService.Get(relation.ChildId, childObjectType);
|
||||
var parent = _entityService.Get(relation.ParentId, parentObjectType);
|
||||
@@ -328,7 +328,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
{
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.ChildObjectType);
|
||||
yield return _entityService.Get(relation.ChildId, objectType);
|
||||
}
|
||||
}
|
||||
@@ -342,7 +342,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
{
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
|
||||
var objectType = ObjectTypes.GetUmbracoObjectType(relation.ParentObjectType);
|
||||
yield return _entityService.Get(relation.ParentId, objectType);
|
||||
}
|
||||
}
|
||||
@@ -356,8 +356,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
{
|
||||
foreach (var relation in relations)
|
||||
{
|
||||
var childObjectType = ObjectTypes.GetUmbracoObjectType(relation.RelationType.ChildObjectType);
|
||||
var parentObjectType = ObjectTypes.GetUmbracoObjectType(relation.RelationType.ParentObjectType);
|
||||
var childObjectType = ObjectTypes.GetUmbracoObjectType(relation.ChildObjectType);
|
||||
var parentObjectType = ObjectTypes.GetUmbracoObjectType(relation.ParentObjectType);
|
||||
|
||||
var child = _entityService.Get(relation.ChildId, childObjectType);
|
||||
var parent = _entityService.Get(relation.ParentId, parentObjectType);
|
||||
@@ -379,6 +379,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
if (relationType.HasIdentity == false)
|
||||
Save(relationType);
|
||||
|
||||
//TODO: We don't check if this exists first, it will throw some sort of data integrity exception if it already exists, is that ok?
|
||||
|
||||
var relation = new Relation(parentId, childId, relationType);
|
||||
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
|
||||
@@ -245,6 +245,7 @@
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RichTextPreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\DropDownFlexiblePreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\MergeDateAndDateTimePropertyEditor.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_5_0\UpdateRelationTypeTable.cs" />
|
||||
<Compile Include="Models\Editors\UmbracoEntityReference.cs" />
|
||||
<Compile Include="Models\Entities\EntityExtensions.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\PreValueMigratorBase.cs" />
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Tests.Models
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new Relation(9, 8, new RelationType(Guid.NewGuid(), Guid.NewGuid(), "test")
|
||||
var item = new Relation(9, 8, new RelationType("test", "test", false, Guid.NewGuid(), Guid.NewGuid())
|
||||
{
|
||||
Id = 66
|
||||
})
|
||||
@@ -52,7 +52,7 @@ namespace Umbraco.Tests.Models
|
||||
{
|
||||
var ss = new SerializationService(new JsonNetSerializer());
|
||||
|
||||
var item = new Relation(9, 8, new RelationType(Guid.NewGuid(), Guid.NewGuid(), "test")
|
||||
var item = new Relation(9, 8, new RelationType("test", "test", false, Guid.NewGuid(), Guid.NewGuid())
|
||||
{
|
||||
Id = 66
|
||||
})
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Tests.Models
|
||||
[Test]
|
||||
public void Can_Deep_Clone()
|
||||
{
|
||||
var item = new RelationType(Guid.NewGuid(), Guid.NewGuid(), "test")
|
||||
var item = new RelationType("test", "test", false, Guid.NewGuid(), Guid.NewGuid())
|
||||
{
|
||||
Id = 66,
|
||||
CreateDate = DateTime.Now,
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Tests.Models
|
||||
{
|
||||
var ss = new SerializationService(new JsonNetSerializer());
|
||||
|
||||
var item = new RelationType(Guid.NewGuid(), Guid.NewGuid(), "test")
|
||||
var item = new RelationType("test", "test", false, Guid.NewGuid(), Guid.NewGuid())
|
||||
{
|
||||
Id = 66,
|
||||
CreateDate = DateTime.Now,
|
||||
|
||||
@@ -260,8 +260,16 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
public void CreateTestData()
|
||||
{
|
||||
var relateContent = new RelationType(Constants.ObjectTypes.Document, new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"), "relateContentOnCopy") { IsBidirectional = true, Name = "Relate Content on Copy" };
|
||||
var relateContentType = new RelationType(Constants.ObjectTypes.DocumentType, new Guid("A2CB7800-F571-4787-9638-BC48539A0EFB"), "relateContentTypeOnCopy") { IsBidirectional = true, Name = "Relate ContentType on Copy" };
|
||||
var relateContent = new RelationType(
|
||||
"Relate Content on Copy", "relateContentOnCopy", true,
|
||||
Constants.ObjectTypes.Document,
|
||||
new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"));
|
||||
|
||||
var relateContentType = new RelationType("Relate ContentType on Copy",
|
||||
"relateContentTypeOnCopy",
|
||||
true,
|
||||
Constants.ObjectTypes.DocumentType,
|
||||
new Guid("A2CB7800-F571-4787-9638-BC48539A0EFB"));
|
||||
|
||||
var provider = TestObjects.GetScopeProvider(Logger);
|
||||
using (var scope = provider.CreateScope())
|
||||
|
||||
@@ -42,9 +42,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
var repository = CreateRepository(provider);
|
||||
|
||||
// Act
|
||||
var relateMemberToContent = new RelationType(Constants.ObjectTypes.Member,
|
||||
Constants.ObjectTypes.Document,
|
||||
"relateMemberToContent") { IsBidirectional = true, Name = "Relate Member to Content" };
|
||||
var relateMemberToContent = new RelationType("Relate Member to Content", "relateMemberToContent", true, Constants.ObjectTypes.Member, Constants.ObjectTypes.Document);
|
||||
|
||||
repository.Save(relateMemberToContent);
|
||||
|
||||
@@ -226,8 +224,8 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
|
||||
public void CreateTestData()
|
||||
{
|
||||
var relateContent = new RelationType(Constants.ObjectTypes.Document, new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"), "relateContentOnCopy") { IsBidirectional = true, Name = "Relate Content on Copy" };
|
||||
var relateContentType = new RelationType(Constants.ObjectTypes.DocumentType, new Guid("A2CB7800-F571-4787-9638-BC48539A0EFB"), "relateContentTypeOnCopy") { IsBidirectional = true, Name = "Relate ContentType on Copy" };
|
||||
var relateContent = new RelationType("Relate Content on Copy", "relateContentOnCopy", true, Constants.ObjectTypes.Document, new Guid("C66BA18E-EAF3-4CFF-8A22-41B16D66A972"));
|
||||
var relateContentType = new RelationType("Relate ContentType on Copy", "relateContentTypeOnCopy", true, Constants.ObjectTypes.DocumentType, new Guid("A2CB7800-F571-4787-9638-BC48539A0EFB"));
|
||||
|
||||
var provider = TestObjects.GetScopeProvider(Logger);
|
||||
using (var scope = ScopeProvider.CreateScope())
|
||||
|
||||
@@ -1778,7 +1778,7 @@ namespace Umbraco.Tests.Services
|
||||
admin.StartContentIds = new[] {content1.Id};
|
||||
ServiceContext.UserService.Save(admin);
|
||||
|
||||
ServiceContext.RelationService.Save(new RelationType(Constants.ObjectTypes.Document, Constants.ObjectTypes.Document, "test"));
|
||||
ServiceContext.RelationService.Save(new RelationType("test", "test", false, Constants.ObjectTypes.Document, Constants.ObjectTypes.Document));
|
||||
Assert.IsNotNull(ServiceContext.RelationService.Relate(content1, content2, "test"));
|
||||
|
||||
ServiceContext.PublicAccessService.Save(new PublicAccessEntry(content1, content2, content2, new List<PublicAccessRule>
|
||||
|
||||
@@ -4,24 +4,91 @@ using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.TestHelpers.Entities;
|
||||
using Umbraco.Tests.Testing;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
[TestFixture]
|
||||
[Apartment(ApartmentState.STA)]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class RelationServiceTests : TestWithSomeContentBase
|
||||
{
|
||||
[Test]
|
||||
public void Can_Create_RelationType_Without_Name()
|
||||
{
|
||||
var rs = ServiceContext.RelationService;
|
||||
var rt = new RelationType(Constants.ObjectTypes.Document, Constants.ObjectTypes.Document, "repeatedEventOccurence");
|
||||
IRelationType rt = new RelationType("Test", "repeatedEventOccurence", false, Constants.ObjectTypes.Document, Constants.ObjectTypes.Media);
|
||||
|
||||
Assert.DoesNotThrow(() => rs.Save(rt));
|
||||
|
||||
Assert.AreEqual(rt.Name, "repeatedEventOccurence");
|
||||
//re-get
|
||||
rt = ServiceContext.RelationService.GetRelationTypeById(rt.Id);
|
||||
|
||||
Assert.AreEqual("Test", rt.Name);
|
||||
Assert.AreEqual("repeatedEventOccurence", rt.Alias);
|
||||
Assert.AreEqual(false, rt.IsBidirectional);
|
||||
Assert.AreEqual(Constants.ObjectTypes.Document, rt.ChildObjectType.Value);
|
||||
Assert.AreEqual(Constants.ObjectTypes.Media, rt.ParentObjectType.Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Create_Relation_Type_Without_Object_Types()
|
||||
{
|
||||
var rs = ServiceContext.RelationService;
|
||||
IRelationType rt = new RelationType("repeatedEventOccurence", "repeatedEventOccurence", false, null, null);
|
||||
|
||||
Assert.DoesNotThrow(() => rs.Save(rt));
|
||||
|
||||
//re-get
|
||||
rt = ServiceContext.RelationService.GetRelationTypeById(rt.Id);
|
||||
|
||||
Assert.IsNull(rt.ChildObjectType);
|
||||
Assert.IsNull(rt.ParentObjectType);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Relation_Returns_Parent_Child_Object_Types_When_Creating()
|
||||
{
|
||||
var r = CreateNewRelation("Test", "test");
|
||||
|
||||
Assert.AreEqual(Constants.ObjectTypes.Document, r.ParentObjectType);
|
||||
Assert.AreEqual(Constants.ObjectTypes.Media, r.ChildObjectType);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Relation_Returns_Parent_Child_Object_Types_When_Getting()
|
||||
{
|
||||
var r = CreateNewRelation("Test", "test");
|
||||
|
||||
// re-get
|
||||
r = ServiceContext.RelationService.GetById(r.Id);
|
||||
|
||||
Assert.AreEqual(Constants.ObjectTypes.Document, r.ParentObjectType);
|
||||
Assert.AreEqual(Constants.ObjectTypes.Media, r.ChildObjectType);
|
||||
}
|
||||
|
||||
private IRelation CreateNewRelation(string name, string alias)
|
||||
{
|
||||
var rs = ServiceContext.RelationService;
|
||||
var rt = new RelationType(name, alias, false, null, null);
|
||||
rs.Save(rt);
|
||||
|
||||
var ct = MockedContentTypes.CreateBasicContentType();
|
||||
ServiceContext.ContentTypeService.Save(ct);
|
||||
|
||||
var mt = MockedContentTypes.CreateImageMediaType("img");
|
||||
ServiceContext.MediaTypeService.Save(mt);
|
||||
|
||||
var c1 = MockedContent.CreateBasicContent(ct);
|
||||
var c2 = MockedMedia.CreateMediaImage(mt, -1);
|
||||
ServiceContext.ContentService.Save(c1);
|
||||
ServiceContext.MediaService.Save(c2);
|
||||
|
||||
var r = new Relation(c1.Id, c2.Id, rt);
|
||||
ServiceContext.RelationService.Save(r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//TODO: Create a relation for entities of the wrong Entity Type (GUID) based on the Relation Type's defined parent/child object types
|
||||
|
||||
@@ -84,11 +84,7 @@ namespace Umbraco.Web.Editors
|
||||
/// <returns>A <see cref="HttpResponseMessage"/> containing the persisted relation type's ID.</returns>
|
||||
public HttpResponseMessage PostCreate(RelationTypeSave relationType)
|
||||
{
|
||||
var relationTypePersisted = new RelationType(relationType.ChildObjectType, relationType.ParentObjectType, relationType.Name.ToSafeAlias(true))
|
||||
{
|
||||
Name = relationType.Name,
|
||||
IsBidirectional = relationType.IsBidirectional
|
||||
};
|
||||
var relationTypePersisted = new RelationType(relationType.Name, relationType.Name.ToSafeAlias(true), relationType.IsBidirectional, relationType.ChildObjectType, relationType.ParentObjectType);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
/// </summary>
|
||||
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
|
||||
[DataMember(Name = "parentObjectType", IsRequired = true)]
|
||||
public Guid ParentObjectType { get; set; }
|
||||
public Guid? ParentObjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Parent's object type name.
|
||||
@@ -38,7 +38,7 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
/// </summary>
|
||||
/// <remarks>Corresponds to the NodeObjectType in the umbracoNode table</remarks>
|
||||
[DataMember(Name = "childObjectType", IsRequired = true)]
|
||||
public Guid ChildObjectType { get; set; }
|
||||
public Guid? ChildObjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Child's object type name.
|
||||
|
||||
@@ -29,8 +29,8 @@ namespace Umbraco.Web.Models.Mapping
|
||||
target.Path = "-1," + source.Id;
|
||||
|
||||
// Set the "friendly" names for the parent and child object types
|
||||
target.ParentObjectTypeName = ObjectTypes.GetUmbracoObjectType(source.ParentObjectType).GetFriendlyName();
|
||||
target.ChildObjectTypeName = ObjectTypes.GetUmbracoObjectType(source.ChildObjectType).GetFriendlyName();
|
||||
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;
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -ParentName -ChildName
|
||||
|
||||
Reference in New Issue
Block a user