diff --git a/src/NHibernate.Test/MappingByCode/ExplicitMappingTests/JoinDynamicComponentTests.cs b/src/NHibernate.Test/MappingByCode/ExplicitMappingTests/JoinDynamicComponentTests.cs new file mode 100644 index 00000000000..5a8f6c38ee9 --- /dev/null +++ b/src/NHibernate.Test/MappingByCode/ExplicitMappingTests/JoinDynamicComponentTests.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections; +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NHibernate.Mapping.ByCode.Conformist; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.ExplicitMappingTests +{ + public class JoinDynamicComponentTests + { + public class MyClass + { + public virtual int Code { get; set; } + public virtual string JoinedName { get; set; } + public virtual MyOther Relation { get; set; } + public virtual MyOther JoinedRelation { get; set; } + public virtual IDictionary Attributes { get; set; } + public virtual IDictionary JoinedAttributes { get; set; } + } + + public class MyOther + { + public int Id { get; set; } + } + + public class MyClassMap : ClassMapping + { + public MyClassMap() + { + // basic table related properties + ManyToOne(x => x.Relation); + Component(p => p.Attributes, + new + { + IsVisible = false, + Hash = default(Guid), + Reference = default(MyOther) + }, + m => + { + m.Property(p => p.IsVisible); + m.Property(p => p.Hash); + m.ManyToOne(p => p.Reference); + }); + Property(x => x.Code); + + // joined table stuff + Join("JoinedAttributes", x => + { + x.Property(p => p.JoinedName); + x.Component(p => p.JoinedAttributes, + new + { + OtherReference = default(MyOther), + Description = string.Empty, + Age = 0, + }, + m => + { + m.ManyToOne(p => p.OtherReference); + m.Property(p => p.Description); + m.Property(p => p.Age); + }); + x.ManyToOne(p => p.JoinedRelation); + }); + } + } + + protected HbmClass CompileClassMapping() + { + var mapper = new ModelMapper(); + mapper.AddMapping(typeof(MyClassMap)); + + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + var hbmClass = hbmMapping.RootClasses[0]; + + return hbmClass; + } + + [Test] + public void WhenPropertyIsMappedOnRootThenItBelonsToRootTable() + { + // + var hbmClass = CompileClassMapping(); + hbmClass.Should().Not.Be.Null(); + + var rootProperties = hbmClass.Properties; + // p.Name == "Code"); + + hbmPropCode.Should().Not.Be.Null(); + hbmPropCode.Should().Be.OfType(); + } + + [Test] + public void WhenDynamicComponentIsMappedOnRootThenItBelonsToRootTable() + { + // + var hbmClass = CompileClassMapping(); + hbmClass.Should().Not.Be.Null(); + + var rootProperties = hbmClass.Properties; + // p.Name == "Attributes") + ; + + hbmPropAttributes.Should().Not.Be.Null(); + hbmPropAttributes.Should().Be.OfType(); + } + + [Test] + public void WhenRelationIsMappedOnRootThenItBelonsToRootTable() + { + // + var hbmClass = CompileClassMapping(); + hbmClass.Should().Not.Be.Null(); + + var rootProperties = hbmClass.Properties; + // p.Name == "Relation"); + + hbmPropRelation.Should().Not.Be.Null(); + hbmPropRelation.Should().Be.OfType(); + } + + [Test] + public void WhenJoinedPropertyIsMappedOnJoinThenItBelonsToJoinTable() + { + // + var hbmClass = CompileClassMapping(); + hbmClass.Should().Not.Be.Null(); + + // + var hbmJoined = hbmClass.Joins.FirstOrDefault(); + hbmJoined.Should().Not.Be.Null(); + + var rootProperties = hbmJoined.Properties; + // + // p.Name == "JoinedName"); + + hbmPropJoinedName.Should().Not.Be.Null(); + hbmPropJoinedName.Should().Be.OfType(); + } + + [Test] + public void WhenJoinedRelationIsMappedOnJoinThenItBelonsToJoinTable() + { + // + var hbmClass = CompileClassMapping(); + hbmClass.Should().Not.Be.Null(); + + // + var hbmJoined = hbmClass.Joins.FirstOrDefault(); + hbmJoined.Should().Not.Be.Null(); + + var rootProperties = hbmJoined.Properties; + // + // p.Name == "JoinedRelation"); + + hbmPropJoinedRelation.Should().Not.Be.Null(); + hbmPropJoinedRelation.Should().Be.OfType(); + } + + [Test] + public void WhenJoinedDynamicComponentIsMappedOnJoinThenItBelonsToJoinTable() + { + // + var hbmClass = CompileClassMapping(); + hbmClass.Should().Not.Be.Null(); + + // + var hbmJoined = hbmClass.Joins.FirstOrDefault(); + hbmJoined.Should().Not.Be.Null(); + + var rootProperties = hbmJoined.Properties; + // + // + var hbmPropJoinedAttributes = rootProperties + .FirstOrDefault(p => p.Name == "JoinedAttributes"); + + hbmPropJoinedAttributes.Should().Not.Be.Null(); + hbmPropJoinedAttributes.Should().Be.OfType(); + } + + // [Test] + public void Expected_XML_Result() + { + var mapper = new ModelMapper(); + mapper.AddMapping(typeof(MyClassMap)); + var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities(); + + var mappingXml = mapping.AsString(); + Assert.AreEqual(mappingXml, +@" + + + + + + + + + + + + + + + + + + + + + +"); + } + + } +} \ No newline at end of file diff --git a/src/NHibernate.Test/NHibernate.Test.csproj b/src/NHibernate.Test/NHibernate.Test.csproj index 2533d1bd023..c5c9a4adf9d 100644 --- a/src/NHibernate.Test/NHibernate.Test.csproj +++ b/src/NHibernate.Test/NHibernate.Test.csproj @@ -582,6 +582,7 @@ + diff --git a/src/NHibernate/Mapping/ByCode/IJoinMapper.cs b/src/NHibernate/Mapping/ByCode/IJoinMapper.cs index e73ea8a6667..cf880907cb4 100644 --- a/src/NHibernate/Mapping/ByCode/IJoinMapper.cs +++ b/src/NHibernate/Mapping/ByCode/IJoinMapper.cs @@ -13,7 +13,7 @@ public interface IJoinAttributesMapper : IEntitySqlsMapper void Fetch(FetchKind fetchMode); } - public interface IJoinMapper : IJoinAttributesMapper, ICollectionPropertiesContainerMapper, IBasePlainPropertyContainerMapper { } + public interface IJoinMapper : IJoinAttributesMapper, IPropertyContainerMapper { } public interface IJoinAttributesMapper : IEntitySqlsMapper where TEntity : class { diff --git a/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/JoinCustomizer.cs b/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/JoinCustomizer.cs index b6dfd2b0f2f..a7946306ea0 100644 --- a/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/JoinCustomizer.cs +++ b/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/JoinCustomizer.cs @@ -132,6 +132,14 @@ protected override void RegisterComponentMapping(Expression(Expression> property + , Action> mapping) + { + MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(property); + ExplicitDeclarationsHolder.AddAsPropertySplit(new SplitDefinition(typeof(TEntity), splitGroupId, member)); + base.RegisterDynamicComponentMapping(property, mapping); + } + protected override void RegisterManyToOneMapping(Expression> property, Action mapping) { MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(property); diff --git a/src/NHibernate/Mapping/ByCode/ModelMapper.cs b/src/NHibernate/Mapping/ByCode/ModelMapper.cs index a79e167efd6..650dbff79a5 100644 --- a/src/NHibernate/Mapping/ByCode/ModelMapper.cs +++ b/src/NHibernate/Mapping/ByCode/ModelMapper.cs @@ -864,6 +864,10 @@ private void MapSplitProperties(System.Type propertiesContainerType, IEnumerable { MapComponent(member, memberPath, propertyType, propertiesContainer, propertiesContainerType); } + else if (modelInspector.IsDynamicComponent(member)) + { + MapDynamicComponent(member, memberPath, propertyType, propertiesContainer); + } else { MapProperty(member, memberPath, propertiesContainer);