From: <fab...@us...> - 2011-04-27 18:54:54
|
Revision: 5775 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5775&view=rev Author: fabiomaulo Date: 2011-04-27 18:54:47 +0000 (Wed, 27 Apr 2011) Log Message: ----------- The end composed-id Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IClassMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICompositeIdMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ClassCustomizer.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ComponentAsIdLikeComponetAttributesMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComponentAsIdCustomizer.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComposedIdCustomizer.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/ComponentAsIdTests.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/ComposedIdTests.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/IClassMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IClassMapper.cs 2011-04-27 14:36:13 UTC (rev 5774) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/IClassMapper.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -42,10 +42,10 @@ void Id<TProperty>(Expression<Func<TEntity, TProperty>> idProperty, Action<IIdMapper> idMapper); void Id(FieldInfo idProperty, Action<IIdMapper> idMapper); - //void ComponentAsId<TComponent>(Expression<Func<TEntity, TComponent>> idProperty) where TComponent : class; - //void ComponentAsId<TComponent>(Expression<Func<TEntity, TComponent>> idProperty, Action<IComponentAsIdMapper<TComponent>> idMapper) where TComponent : class; + void ComponentAsId<TComponent>(Expression<Func<TEntity, TComponent>> idProperty) where TComponent : class; + void ComponentAsId<TComponent>(Expression<Func<TEntity, TComponent>> idProperty, Action<IComponentAsIdMapper<TComponent>> idMapper) where TComponent : class; - //void ComposedId(Action<IComposedIdMapper<TEntity>> idPropertiesMapping); + void ComposedId(Action<IComposedIdMapper<TEntity>> idPropertiesMapping); void Discriminator(Action<IDiscriminatorMapper> discriminatorMapping); void DiscriminatorValue(object value); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICompositeIdMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICompositeIdMapper.cs 2011-04-27 14:36:13 UTC (rev 5774) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICompositeIdMapper.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -23,6 +23,7 @@ void Class<TConcrete>() where TConcrete : TComponent; } - public interface IComponentAsIdMapper<TComponent> : IComponentAsIdAttributesMapper<TComponent>, IMinimalPlainPropertyContainerMapper<TComponent> where TComponent : class { } + public interface IComponentAsIdMapper<TComponent> : IComponentAsIdAttributesMapper<TComponent>, IMinimalPlainPropertyContainerMapper<TComponent> + { } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ComponentAsIdLikeComponetAttributesMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ComponentAsIdLikeComponetAttributesMapper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ComponentAsIdLikeComponetAttributesMapper.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -0,0 +1,53 @@ +using System; +using System.Reflection; + +namespace NHibernate.Mapping.ByCode.Impl +{ + public class ComponentAsIdLikeComponetAttributesMapper : IComponentAttributesMapper + { + private readonly IComponentAsIdMapper realMapper; + + public ComponentAsIdLikeComponetAttributesMapper(IComponentAsIdMapper realMapper) + { + if (realMapper == null) + { + throw new ArgumentNullException("realMapper"); + } + this.realMapper = realMapper; + } + + #region IComponentAttributesMapper Members + + public void Access(Accessor accessor) + { + realMapper.Access(accessor); + } + + public void Access(System.Type accessorType) + { + realMapper.Access(accessorType); + } + + public void OptimisticLock(bool takeInConsiderationForOptimisticLock) {} + + public void Parent(MemberInfo parent) + { + // the mapping of the Parent can be used as a ManyToOne but could be strange to have a bidirectional relation in the PK + } + + public void Parent(MemberInfo parent, Action<IComponentParentMapper> parentMapping) {} + + public void Update(bool consideredInUpdateQuery) {} + + public void Insert(bool consideredInInsertQuery) {} + + public void Lazy(bool isLazy) {} + + public void Class(System.Type componentType) + { + realMapper.Class(componentType); + } + + #endregion + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs 2011-04-27 14:36:13 UTC (rev 5774) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersHolder.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -33,6 +33,9 @@ private readonly Dictionary<PropertyPath, List<Action<IComponentAttributesMapper>>> componentPropertyCustomizers = new Dictionary<PropertyPath, List<Action<IComponentAttributesMapper>>>(); + private readonly Dictionary<PropertyPath, List<Action<IComponentAsIdAttributesMapper>>> componentAsIdPropertyCustomizers = + new Dictionary<PropertyPath, List<Action<IComponentAsIdAttributesMapper>>>(); + private readonly Dictionary<PropertyPath, List<Action<IDynamicComponentAttributesMapper>>> dynamicComponentCustomizers = new Dictionary<PropertyPath, List<Action<IDynamicComponentAttributesMapper>>>(); @@ -162,6 +165,11 @@ AddCustomizer(componentPropertyCustomizers, member, propertyCustomizer); } + public void AddCustomizer(PropertyPath member, Action<IComponentAsIdAttributesMapper> propertyCustomizer) + { + AddCustomizer(componentAsIdPropertyCustomizers, member, propertyCustomizer); + } + public void AddCustomizer(PropertyPath member, Action<IDynamicComponentAttributesMapper> propertyCustomizer) { AddCustomizer(dynamicComponentCustomizers, member, propertyCustomizer); @@ -282,6 +290,11 @@ InvokeCustomizers(componentPropertyCustomizers, member, mapper); } + public void InvokeCustomizers(PropertyPath member, IComponentAsIdAttributesMapper mapper) + { + InvokeCustomizers(componentAsIdPropertyCustomizers, member, mapper); + } + public void InvokeCustomizers(PropertyPath member, IDynamicComponentAttributesMapper mapper) { InvokeCustomizers(dynamicComponentCustomizers, member, mapper); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ClassCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ClassCustomizer.cs 2011-04-27 14:36:13 UTC (rev 5774) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ClassCustomizer.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -52,6 +52,23 @@ CustomizersHolder.AddCustomizer(typeof(TEntity), m => m.Id(idProperty, idMapper)); } + public void ComponentAsId<TComponent>(Expression<Func<TEntity, TComponent>> idProperty) where TComponent : class + { + ComponentAsId(idProperty, x => { }); + } + + public void ComponentAsId<TComponent>(Expression<Func<TEntity, TComponent>> idProperty, Action<IComponentAsIdMapper<TComponent>> idMapper) where TComponent : class + { + var member = TypeExtensions.DecodeMemberAccessExpression(idProperty); + var propertyPath = new PropertyPath(null, member); + idMapper(new ComponentAsIdCustomizer<TComponent>(ExplicitDeclarationsHolder, CustomizersHolder, propertyPath)); + } + + public void ComposedId(Action<IComposedIdMapper<TEntity>> idPropertiesMapping) + { + idPropertiesMapping(new ComposedIdCustomizer<TEntity>(ExplicitDeclarationsHolder, CustomizersHolder)); + } + public void Discriminator(Action<IDiscriminatorMapper> discriminatorMapping) { CustomizersHolder.AddCustomizer(typeof (TEntity), (IClassMapper m) => m.Discriminator(discriminatorMapping)); Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComponentAsIdCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComponentAsIdCustomizer.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComponentAsIdCustomizer.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -0,0 +1,37 @@ +using System; + +namespace NHibernate.Mapping.ByCode.Impl.CustomizersImpl +{ + public class ComponentAsIdCustomizer<TComponent> : PropertyContainerCustomizer<TComponent>, IComponentAsIdMapper<TComponent> where TComponent : class + { + public ComponentAsIdCustomizer(IModelExplicitDeclarationsHolder explicitDeclarationsHolder, ICustomizersHolder customizersHolder, PropertyPath propertyPath) + : base(explicitDeclarationsHolder, customizersHolder, propertyPath) + { + if (explicitDeclarationsHolder == null) + { + throw new ArgumentNullException("explicitDeclarationsHolder"); + } + if (propertyPath == null) + { + throw new ArgumentNullException("propertyPath"); + } + explicitDeclarationsHolder.AddAsComponent(typeof (TComponent)); + explicitDeclarationsHolder.AddAsPoid(propertyPath.LocalMember); + } + + public void Class<TConcrete>() where TConcrete : TComponent + { + CustomizersHolder.AddCustomizer(PropertyPath, (IComponentAsIdAttributesMapper m) => m.Class(typeof(TConcrete))); + } + + public void Access(Accessor accessor) + { + CustomizersHolder.AddCustomizer(PropertyPath, (IComponentAsIdAttributesMapper m) => m.Access(accessor)); + } + + public void Access(System.Type accessorType) + { + CustomizersHolder.AddCustomizer(PropertyPath, (IComponentAsIdAttributesMapper m) => m.Access(accessorType)); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComposedIdCustomizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComposedIdCustomizer.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/ComposedIdCustomizer.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -0,0 +1,24 @@ +using System.Reflection; + +namespace NHibernate.Mapping.ByCode.Impl.CustomizersImpl +{ + public class ComposedIdCustomizer<TEntity> : PropertyContainerCustomizer<TEntity>, IComposedIdMapper<TEntity> where TEntity : class + { + public ComposedIdCustomizer(IModelExplicitDeclarationsHolder explicitDeclarationsHolder, ICustomizersHolder customizersHolder) + : base(explicitDeclarationsHolder, customizersHolder, null) {} + + protected override void RegisterPropertyMapping<TProperty>(System.Linq.Expressions.Expression<System.Func<TEntity, TProperty>> property, System.Action<IPropertyMapper> mapping) + { + MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(property); + ExplicitDeclarationsHolder.AddAsPartOfComposedId(member); + base.RegisterPropertyMapping(property, mapping); + } + + protected override void RegisterManyToOneMapping<TProperty>(System.Linq.Expressions.Expression<System.Func<TEntity, TProperty>> property, System.Action<IManyToOneMapper> mapping) + { + MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(property); + ExplicitDeclarationsHolder.AddAsPartOfComposedId(member); + base.RegisterManyToOneMapping(property, mapping); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs 2011-04-27 14:36:13 UTC (rev 5774) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/ICustomizersHolder.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -24,6 +24,7 @@ void AddCustomizer(PropertyPath member, Action<IIdBagPropertiesMapper> propertyCustomizer); void AddCustomizer(PropertyPath member, Action<ICollectionPropertiesMapper> propertyCustomizer); void AddCustomizer(PropertyPath member, Action<IComponentAttributesMapper> propertyCustomizer); + void AddCustomizer(PropertyPath member, Action<IComponentAsIdAttributesMapper> propertyCustomizer); void AddCustomizer(PropertyPath member, Action<IDynamicComponentAttributesMapper> propertyCustomizer); void InvokeCustomizers(System.Type type, IClassMapper mapper); @@ -44,6 +45,7 @@ void InvokeCustomizers(PropertyPath member, IMapPropertiesMapper mapper); void InvokeCustomizers(PropertyPath member, IIdBagPropertiesMapper mapper); void InvokeCustomizers(PropertyPath member, IComponentAttributesMapper mapper); + void InvokeCustomizers(PropertyPath member, IComponentAsIdAttributesMapper mapper); void InvokeCustomizers(PropertyPath member, IDynamicComponentAttributesMapper mapper); #region Collection Element relations invokers Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs 2011-04-27 14:36:13 UTC (rev 5774) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ModelMapper.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -731,7 +731,42 @@ InvokeBeforeMapClass(type, classMapper); InvokeClassCustomizers(type, classMapper); - MemberInfo[] naturalIdPropeties = persistentProperties.Where(mi => modelInspector.IsMemberOfNaturalId(mi)).ToArray(); + if (poidPropertyOrField != null && modelInspector.IsComponent(poidPropertyOrField.GetPropertyOrFieldType())) + { + classMapper.ComponentAsId(poidPropertyOrField, compoAsId => + { + var memberPath = new PropertyPath(null, poidPropertyOrField); + var componentMapper = new ComponentAsIdLikeComponetAttributesMapper(compoAsId); + InvokeBeforeMapComponent(memberPath, componentMapper); + + System.Type componentType = poidPropertyOrField.GetPropertyOrFieldType(); + IEnumerable<MemberInfo> componentPersistentProperties = + membersProvider.GetComponentMembers(componentType).Where(p => modelInspector.IsPersistentProperty(p)); + + customizerHolder.InvokeCustomizers(componentType, componentMapper); + ForEachMemberPath(poidPropertyOrField, memberPath, pp => customizerHolder.InvokeCustomizers(pp, compoAsId)); + InvokeAfterMapComponent(memberPath, componentMapper); + + foreach (MemberInfo property in componentPersistentProperties) + { + MapComposedIdProperties(compoAsId, new PropertyPath(memberPath, property)); + } + }); + } + + MemberInfo[] composedIdPropeties = persistentProperties.Where(mi => modelInspector.IsMemberOfComposedId(mi)).ToArray(); + if (composedIdPropeties.Length > 0) + { + classMapper.ComposedId(composedIdMapper => + { + foreach (MemberInfo property in composedIdPropeties) + { + MapComposedIdProperties(composedIdMapper, new PropertyPath(null, property)); + } + }); + } + + MemberInfo[] naturalIdPropeties = persistentProperties.Except(composedIdPropeties).Where(mi => modelInspector.IsMemberOfNaturalId(mi)).ToArray(); if (naturalIdPropeties.Length > 0) { classMapper.NaturalId(naturalIdMapper => @@ -743,7 +778,7 @@ }); } var splitGroups = modelInspector.GetPropertiesSplits(type); - var propertiesToMap = persistentProperties.Where(mi => !modelInspector.IsVersion(mi) && !modelInspector.IsVersion(mi.GetMemberFromDeclaringType())).Except(naturalIdPropeties).ToList(); + var propertiesToMap = persistentProperties.Except(naturalIdPropeties).Except(composedIdPropeties).Where(mi => !modelInspector.IsVersion(mi) && !modelInspector.IsVersion(mi.GetMemberFromDeclaringType())).ToList(); var propertiesInSplits = new HashSet<MemberInfo>(); foreach (var splitGroup in splitGroups) { @@ -838,6 +873,34 @@ } } + private void MapComposedIdProperties(IMinimalPlainPropertyContainerMapper composedIdMapper, PropertyPath propertyPath) + { + MemberInfo member = propertyPath.LocalMember; + System.Type propertyType = member.GetPropertyOrFieldType(); + var memberPath = propertyPath; + if (modelInspector.IsProperty(member)) + { + MapProperty(member, memberPath, composedIdMapper); + } + else if (modelInspector.IsManyToOne(member)) + { + MapManyToOne(member, memberPath, composedIdMapper); + } + else if (modelInspector.IsAny(member) || modelInspector.IsComponent(propertyType) || + modelInspector.IsOneToOne(member) || modelInspector.IsSet(member) + || modelInspector.IsDictionary(member) || modelInspector.IsArray(member) + || modelInspector.IsList(member) || modelInspector.IsBag(member)) + { + throw new ArgumentOutOfRangeException("propertyPath", + string.Format("The property {0} of {1} can't be part of composite-id.", + member.Name, member.DeclaringType)); + } + else + { + MapProperty(member, memberPath, composedIdMapper); + } + } + private void MapNaturalIdProperties(System.Type rootEntityType, INaturalIdMapper naturalIdMapper, MemberInfo property) { MemberInfo member = property; @@ -973,7 +1036,7 @@ }); } - private void MapProperty(MemberInfo member, PropertyPath propertyPath, IBasePlainPropertyContainerMapper propertiesContainer) + private void MapProperty(MemberInfo member, PropertyPath propertyPath, IMinimalPlainPropertyContainerMapper propertiesContainer) { propertiesContainer.Property(member, propertyMapper => { @@ -1165,7 +1228,7 @@ }); } - private void MapManyToOne(MemberInfo member, PropertyPath propertyPath, IBasePlainPropertyContainerMapper propertiesContainer) + private void MapManyToOne(MemberInfo member, PropertyPath propertyPath, IMinimalPlainPropertyContainerMapper propertiesContainer) { propertiesContainer.ManyToOne(member, manyToOneMapper => { Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-04-27 14:36:13 UTC (rev 5774) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-04-27 18:54:47 UTC (rev 5775) @@ -297,8 +297,11 @@ <Compile Include="Mapping\ByCode\Conformist\UnionSubclassMapping.cs" /> <Compile Include="Mapping\ByCode\ICompositeIdMapper.cs" /> <Compile Include="Mapping\ByCode\IDynamicComponentAttributesMapper.cs" /> + <Compile Include="Mapping\ByCode\Impl\ComponentAsIdLikeComponetAttributesMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\ComponentAsIdMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\ComposedIdMapper.cs" /> + <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\ComponentAsIdCustomizer.cs" /> + <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\ComposedIdCustomizer.cs" /> <Compile Include="Mapping\ByCode\Impl\CustomizersImpl\DynamicComponentCustomizer.cs" /> <Compile Include="Mapping\ByCode\Impl\DynamicComponentMapper.cs" /> <Compile Include="Mapping\ByCode\PropertyToField.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/ComponentAsIdTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/ComponentAsIdTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/ComponentAsIdTests.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -0,0 +1,157 @@ +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.ExpliticMappingTests +{ + public class ComponentAsIdTests + { + private class MyClass + { + private IMyCompo id; + public IMyCompo Id + { + get { return id; } + set { id = value; } + } + } + + private interface IMyCompo + { + string Code { get; set; } + string Name { get; set; } + } + private class MyComponent : IMyCompo + { + public string Code { get; set; } + public string Name { get; set; } + } + + [Test] + public void WhenPropertyUsedAsComposedIdThenRegister() + { + var inspector = new ExplicitlyDeclaredModel(); + var mapper = new ModelMapper(inspector); + mapper.Class<MyClass>(map => map.ComponentAsId(x => x.Id)); + + inspector.IsPersistentId(For<MyClass>.Property(x => x.Id)).Should().Be.True(); + inspector.IsPersistentProperty(For<MyClass>.Property(x => x.Id)).Should().Be.True(); + inspector.IsComponent(typeof(IMyCompo)).Should().Be.True(); + } + + [Test] + public void WhenMapComponentAsIdThenMapItAndItsProperties() + { + var mapper = new ModelMapper(); + mapper.Class<MyClass>(map => map.ComponentAsId(x => x.Id, idmap => + { + idmap.Property(y => y.Code); + idmap.Property(y => y.Name); + })); + + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + var hbmClass = hbmMapping.RootClasses[0]; + var hbmCompositId = hbmClass.CompositeId; + var keyProperties = hbmCompositId.Items.OfType<HbmKeyProperty>(); + keyProperties.Should().Have.Count.EqualTo(2); + keyProperties.Select(x => x.Name).Should().Have.SameValuesAs("Code", "Name"); + } + + [Test] + public void WhenMapComponentAsIdAttributesThenMapAttributes() + { + var mapper = new ModelMapper(); + mapper.Class<MyClass>(map => map.ComponentAsId(x => x.Id, idmap => + { + idmap.Access(Accessor.Field); + idmap.Class<MyComponent>(); + })); + + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + var hbmClass = hbmMapping.RootClasses[0]; + var hbmCompositId = hbmClass.CompositeId; + hbmCompositId.access.Should().Contain("field"); + hbmCompositId.@class.Should().Contain("MyComponent"); + } + + [Test] + public void WhenMapComponentUsedAsComponentAsIdThenMapItAndItsProperties() + { + var mapper = new ModelMapper(); + mapper.Component<IMyCompo>(x => + { + x.Property(y => y.Code, pm => pm.Length(10)); + x.Property(y => y.Name); + }); + mapper.Class<MyClass>(map => map.ComponentAsId(x => x.Id)); + + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + var hbmClass = hbmMapping.RootClasses[0]; + var hbmCompositId = hbmClass.CompositeId; + var keyProperties = hbmCompositId.Items.OfType<HbmKeyProperty>(); + keyProperties.Should().Have.Count.EqualTo(2); + keyProperties.Select(x => x.Name).Should().Have.SameValuesAs("Code", "Name"); + keyProperties.Where(x => x.Name == "Code").Single().length.Should().Be("10"); + } + + [Test] + public void WhenMapCustomizedComponentUsedAsComponentAsIdWithCustomizationThenUseComponentAsIdCustomization() + { + var mapper = new ModelMapper(); + mapper.Component<IMyCompo>(x => + { + x.Property(y => y.Code, pm=> pm.Length(10)); + x.Property(y => y.Name, pm => pm.Length(20)); + }); + mapper.Class<MyClass>(map => map.ComponentAsId(x => x.Id, idmap => + { + idmap.Property(y => y.Code, pm => pm.Length(15)); + idmap.Property(y => y.Name, pm => pm.Length(25)); + })); + + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + var hbmClass = hbmMapping.RootClasses[0]; + var hbmCompositId = hbmClass.CompositeId; + var keyProperties = hbmCompositId.Items.OfType<HbmKeyProperty>(); + keyProperties.Select(x => x.length).Should().Have.SameValuesAs("15", "25"); + } + + [Test] + public void WhenMapAttributesOfCustomizedComponentUsedAsComponentAsIdWithCustomizationThenUseInComponentAsIdCustomization() + { + var mapper = new ModelMapper(); + mapper.Component<IMyCompo>(x => + { + x.Access(Accessor.Field); + x.Class<MyComponent>(); + }); + mapper.Class<MyClass>(map => map.ComponentAsId(x => x.Id)); + + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + var hbmClass = hbmMapping.RootClasses[0]; + var hbmCompositId = hbmClass.CompositeId; + hbmCompositId.access.Should().Contain("field"); + hbmCompositId.@class.Should().Contain("MyComponent"); + } + + [Test] + public void WhenMapAttributesOfCustomizedComponentUsedAsComponentAsIdWithCustomizationOverrideThenUseComponentAsIdCustomization() + { + var mapper = new ModelMapper(); + mapper.Component<IMyCompo>(x => + { + x.Access(Accessor.Field); + x.Class<MyComponent>(); + }); + mapper.Class<MyClass>(map => map.ComponentAsId(x => x.Id, idmap => idmap.Access(Accessor.NoSetter))); + + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + var hbmClass = hbmMapping.RootClasses[0]; + var hbmCompositId = hbmClass.CompositeId; + hbmCompositId.access.Should().Contain("nosetter"); + hbmCompositId.@class.Should().Contain("MyComponent"); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/ComposedIdTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/ComposedIdTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ExpliticMappingTests/ComposedIdTests.cs 2011-04-27 18:54:47 UTC (rev 5775) @@ -0,0 +1,119 @@ +using System; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.ExpliticMappingTests +{ + public class ComposedIdTests + { + private class MyClass + { + public int Code { get; set; } + private MyOther relation; + public MyOther Relation + { + get { return relation; } + set { relation = value; } + } + } + + private class MyOther + { + public int Id { get; set; } + } + + [Test] + public void WhenPropertyUsedAsComposedIdThenRegister() + { + var inspector = new ExplicitlyDeclaredModel(); + var mapper = new ModelMapper(inspector); + mapper.Class<MyClass>(map => + map.ComposedId(cm=> + { + cm.Property(x => x.Code); + cm.ManyToOne(x => x.Relation); + }) + ); + + inspector.IsMemberOfComposedId(For<MyClass>.Property(x => x.Code)).Should().Be.True(); + inspector.IsMemberOfComposedId(For<MyClass>.Property(x => x.Relation)).Should().Be.True(); + inspector.IsPersistentProperty(For<MyClass>.Property(x => x.Code)).Should().Be.True(); + inspector.IsPersistentProperty(For<MyClass>.Property(x => x.Relation)).Should().Be.True(); + inspector.IsPersistentId(For<MyClass>.Property(x => x.Code)).Should().Be.False(); + inspector.IsPersistentId(For<MyClass>.Property(x => x.Relation)).Should().Be.False(); + } + + [Test] + public void WhenPropertyUsedAsComposedIdThenNotUsedAsSimpleProperties() + { + var mapper = new ModelMapper(); + mapper.Class<MyClass>(map => + map.ComposedId(cm => + { + cm.Property(x => x.Code); + cm.ManyToOne(x => x.Relation); + }) + ); + var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + var hbmClass = hbmMapping.RootClasses[0]; + var hbmCompositId = hbmClass.CompositeId; + hbmCompositId.Items.Should().Have.Count.EqualTo(2); + hbmClass.Properties.Should().Be.Empty(); + } + + [Test] + public void WhenPropertyUsedAsComposedIdAndPropertiesThenNotUsedAsSimpleProperties() + { + var mapper = new ModelMapper(); + mapper.Class<MyClass>(map => + { + map.ComposedId(cm => + { + cm.Property(x => x.Code); + cm.ManyToOne(x => x.Relation); + }); + map.Property(x => x.Code); + map.ManyToOne(x => x.Relation); + } + ); + HbmMapping hbmMapping = mapper.CompileMappingFor(new[] {typeof (MyClass)}); + HbmClass hbmClass = hbmMapping.RootClasses[0]; + HbmCompositeId hbmCompositId = hbmClass.CompositeId; + hbmCompositId.Items.Should().Have.Count.EqualTo(2); + hbmClass.Properties.Should().Be.Empty(); + } + + [Test] + public void WhenPropertyUsedAsComposedIdAndPropertiesAndNaturalIdThenMapOnlyAsComposedId() + { + var mapper = new ModelMapper(); + mapper.Class<MyClass>(map => + { + map.ComposedId(cm => + { + cm.Property(x => x.Code); + cm.ManyToOne(x => x.Relation); + }); + map.NaturalId(nm => + { + nm.Property(x => x.Code); + nm.ManyToOne(x => x.Relation); + }); + map.Property(x => x.Code); + map.ManyToOne(x => x.Relation); + } + ); + HbmMapping hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) }); + HbmClass hbmClass = hbmMapping.RootClasses[0]; + HbmCompositeId hbmCompositId = hbmClass.CompositeId; + hbmCompositId.Items.Should().Have.Count.EqualTo(2); + if(hbmClass.naturalid != null) + { + hbmClass.naturalid.Items.Should().Be.Null(); + } + hbmClass.Properties.Should().Be.Empty(); + } + } +} \ 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-27 14:36:13 UTC (rev 5774) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-27 18:54:47 UTC (rev 5775) @@ -519,6 +519,8 @@ <Compile Include="MappingByCode\ConventionModelMapperTests\VersionOnBaseClassIntegrationTest.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\BagOfNestedComponentsWithParentTest.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\ClassWithComponentsTest.cs" /> + <Compile Include="MappingByCode\ExpliticMappingTests\ComponentAsIdTests.cs" /> + <Compile Include="MappingByCode\ExpliticMappingTests\ComposedIdTests.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\ConformistMappingRegistrationTests\ClassMappingRegistrationTest.cs" /> <Compile Include="MappingByCode\CustomizerHolderMergeTest.cs" /> <Compile Include="MappingByCode\ExplicitlyDeclaredModelTests\SplitPropertiesRegistrationTests.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |