From: <fab...@us...> - 2011-04-08 17:16:35
|
Revision: 5643 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5643&view=rev Author: fabiomaulo Date: 2011-04-08 17:16:28 +0000 (Fri, 08 Apr 2011) Log Message: ----------- Composite-elements with nested-composite-elements fix Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComponentElementCustomizer.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/BagOfNestedComponentsWithParentTest.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComponentElementCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComponentElementCustomizer.cs 2011-04-08 14:47:15 UTC (rev 5642) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComponentElementCustomizer.cs 2011-04-08 17:16:28 UTC (rev 5643) @@ -19,20 +19,25 @@ this.explicitDeclarationsHolder = explicitDeclarationsHolder; this.propertyPath = propertyPath; this.customizersHolder = customizersHolder; + explicitDeclarationsHolder.AddAsComponent(typeof(TComponent)); + if (propertyPath != null) + { + explicitDeclarationsHolder.AddAsPersistentMember(propertyPath.LocalMember); + } } #region IComponentElementMapper<TComponent> Members public void Parent<TProperty>(Expression<Func<TComponent, TProperty>> parent) where TProperty : class { - MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(parent); - customizersHolder.AddCustomizer(typeof (TComponent), (IComponentAttributesMapper x) => x.Parent(member)); + Parent(parent, x => { }); } public void Parent<TProperty>(Expression<Func<TComponent, TProperty>> parent, Action<IComponentParentMapper> parentMapping) where TProperty : class { MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(parent); customizersHolder.AddCustomizer(typeof (TComponent), (IComponentAttributesMapper x) => x.Parent(member, parentMapping)); + explicitDeclarationsHolder.AddAsPersistentMember(member); } public void Update(bool consideredInUpdateQuery) @@ -61,6 +66,8 @@ customizersHolder.AddCustomizer(new PropertyPath(propertyPath, member), mapping); MemberInfo memberOf = TypeExtensions.DecodeMemberAccessExpressionOf(property); customizersHolder.AddCustomizer(new PropertyPath(propertyPath, memberOf), mapping); + explicitDeclarationsHolder.AddAsProperty(member); + explicitDeclarationsHolder.AddAsProperty(memberOf); } public void Property<TProperty>(Expression<Func<TComponent, TProperty>> property) @@ -83,6 +90,8 @@ customizersHolder.AddCustomizer(new PropertyPath(propertyPath, member), mapping); MemberInfo memberOf = TypeExtensions.DecodeMemberAccessExpressionOf(property); customizersHolder.AddCustomizer(new PropertyPath(propertyPath, memberOf), mapping); + explicitDeclarationsHolder.AddAsManyToOneRelation(member); + explicitDeclarationsHolder.AddAsManyToOneRelation(memberOf); } public void ManyToOne<TProperty>(Expression<Func<TComponent, TProperty>> property) where TProperty : class Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/BagOfNestedComponentsWithParentTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/BagOfNestedComponentsWithParentTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/BagOfNestedComponentsWithParentTest.cs 2011-04-08 17:16:28 UTC (rev 5643) @@ -0,0 +1,122 @@ +using System.Collections.Generic; +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.ExpliticMappingTests +{ + public class BagOfNestedComponentsWithParentTest + { + private class Person + { + public int Id { get; set; } + public ICollection<Address> Addresses { get; set; } + } + + private class Address + { + public Person Owner { get; set; } + public string Street { get; set; } + public Number Number { get; set; } + } + + private class Number + { + public Address OwnerAddress { get; set; } + public int Block { get; set; } + } + + [Test] + public void WhenMapClasByClassThenAutodiscoverParent() + { + var mapper = new ModelMapper(); + mapper.Component<Address>(cm => + { + cm.ManyToOne(x => x.Owner); + cm.Property(x => x.Street); + cm.Component(x => x.Number, y => { }); + }); + mapper.Component<Number>(cm => + { + cm.Component(x => x.OwnerAddress, map => { }); + cm.Property(x => x.Block); + }); + mapper.Class<Person>(cm => + { + cm.Id(x => x.Id); + cm.Bag(x => x.Addresses, cp => { }, cr => { }); + }); + HbmMapping mapping = mapper.CompileMappingFor(new[] { typeof(Person) }); + VerifyMapping(mapping); + } + + [Test] + public void WhenMapClassWithWrongElementsThenAutodiscoverParent() + { + // In this case the user will use wrong mapping-elements as ManyToOne and Component (he should realize that it end in an infinite loop) + var mapper = new ModelMapper(); + mapper.Class<Person>(cm => + { + cm.Id(x => x.Id); + cm.Bag(x => x.Addresses, cp => { }, cr => cr.Component(ce => + { + ce.ManyToOne(x => x.Owner); + ce.Property(x => x.Street); + ce.Component(x => x.Number, y => + { + y.Component(x => x.OwnerAddress, map => { }); + y.Property(x => x.Block); + }); + })); + }); + HbmMapping mapping = mapper.CompileMappingFor(new[] { typeof(Person) }); + VerifyMapping(mapping); + } + + [Test] + public void WhenMapClassElementsThenMapParent() + { + var mapper = new ModelMapper(); + mapper.Class<Person>(cm => + { + cm.Id(x => x.Id); + cm.Bag(x => x.Addresses, cp => { }, cr => cr.Component(ce => + { + ce.Parent(x => x.Owner); + ce.Property(x => x.Street); + ce.Component(x => x.Number, y => + { + y.Parent(x => x.OwnerAddress, map => { }); + y.Property(x => x.Block); + }); + })); + }); + HbmMapping mapping = mapper.CompileMappingFor(new[] { typeof(Person) }); + VerifyMapping(mapping); + } + + private void VerifyMapping(HbmMapping mapping) + { + HbmClass rc = mapping.RootClasses.First(r => r.Name.Contains("Person")); + var relation = rc.Properties.First(p => p.Name == "Addresses"); + var collection = (HbmBag)relation; + collection.ElementRelationship.Should().Be.OfType<HbmCompositeElement>(); + var elementRelation = (HbmCompositeElement)collection.ElementRelationship; + elementRelation.Class.Should().Contain("Address"); + elementRelation.Properties.Should().Have.Count.EqualTo(2); + elementRelation.Properties.Select(p => p.Name).Should().Have.SameValuesAs("Street", "Number"); + elementRelation.Parent.Should().Not.Be.Null(); + elementRelation.Parent.name.Should().Be.EqualTo("Owner"); + // Nested + var propertyNestedRelation = elementRelation.Properties.FirstOrDefault(p => p.Name == "Number"); + propertyNestedRelation.Should().Not.Be.Null().And.Be.OfType<HbmNestedCompositeElement>(); + var nestedRelation = (HbmNestedCompositeElement) propertyNestedRelation; + nestedRelation.Class.Should().Contain("Number"); + nestedRelation.Properties.Should().Have.Count.EqualTo(1); + nestedRelation.Parent.Should().Not.Be.Null(); + nestedRelation.Parent.name.Should().Be.EqualTo("OwnerAddress"); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-08 14:47:15 UTC (rev 5642) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-08 17:16:28 UTC (rev 5643) @@ -509,6 +509,7 @@ <Compile Include="Linq\ByMethod\SumTests.cs" /> <Compile Include="Logging\Log4NetLoggerTest.cs" /> <Compile Include="Logging\LoggerProviderTest.cs" /> + <Compile Include="MappingByCode\ExpliticMappingTests\BagOfNestedComponentsWithParentTest.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\ClassWithComponentsTest.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\ConformistMappingRegistrationTests\ClassMappingRegistrationTest.cs" /> <Compile Include="MappingByCode\CustomizerHolderMergeTest.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |