From: <fab...@us...> - 2011-04-12 22:59:32
|
Revision: 5682 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5682&view=rev Author: fabiomaulo Date: 2011-04-12 22:59:26 +0000 (Tue, 12 Apr 2011) Log Message: ----------- ConventionModelMapper with convention for many-to-many table Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/PropertyPathExtensions.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ConventionModelMapperTests/ManyToManyInCollectionTableTests.cs Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs 2011-04-12 19:16:13 UTC (rev 5681) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ConventionModelMapper.cs 2011-04-12 22:59:26 UTC (rev 5682) @@ -17,8 +17,30 @@ { BeforeMapJoinedSubclass += JoinedSubclassKeyAsRootIdColumn; BeforeMapProperty += PropertyColumnName; + BeforeMapList += ManyToManyInCollectionTable; + BeforeMapBag += ManyToManyInCollectionTable; + BeforeMapSet += ManyToManyInCollectionTable; + BeforeMapMap += ManyToManyInCollectionTable; } + protected void ManyToManyInCollectionTable(IModelInspector modelInspector, PropertyPath member, ICollectionPropertiesMapper collectionCustomizer) + { + System.Type propertyType = member.LocalMember.GetPropertyOrFieldType(); + + System.Type fromMany = member.GetContainerEntity(modelInspector); + System.Type toMany = propertyType.DetermineCollectionElementOrDictionaryValueType(); + if(!modelInspector.IsEntity(toMany)) + { + // does not apply when the relation is on the key of the dictionary + // Note: a dictionary may have relation with 3 entities; in this handler we are covering only relations on values + return; + } + var relation = new[] { fromMany, toMany }; + var twoEntitiesNames = (from relationOn in relation orderby relationOn.Name select relationOn.Name).ToArray(); + + collectionCustomizer.Table(string.Format("{0}To{1}", twoEntitiesNames[0], twoEntitiesNames[1])); + } + protected void PropertyColumnName(IModelInspector modelInspector, PropertyPath member, IPropertyMapper propertyCustomizer) { if (member.PreviousPath == null || member.LocalMember == null) @@ -36,7 +58,7 @@ protected void JoinedSubclassKeyAsRootIdColumn(IModelInspector modelInspector, System.Type type, IJoinedSubclassAttributesMapper joinedSubclassCustomizer) { - var idMember = type.GetProperties().Cast<MemberInfo>().Concat(type.GetFields()).FirstOrDefault(mi => ModelInspector.IsPersistentId(mi.GetMemberFromDeclaringType())); + var idMember = type.GetProperties().Cast<MemberInfo>().Concat(type.GetFields()).FirstOrDefault(mi => modelInspector.IsPersistentId(mi.GetMemberFromDeclaringType())); if (idMember != null) { joinedSubclassCustomizer.Key(km => km.Column(idMember.Name)); Modified: trunk/nhibernate/src/NHibernate/Mapping/ByCode/PropertyPathExtensions.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/PropertyPathExtensions.cs 2011-04-12 19:16:13 UTC (rev 5681) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/PropertyPathExtensions.cs 2011-04-12 22:59:26 UTC (rev 5682) @@ -7,6 +7,16 @@ { public static class PropertyPathExtensions { + public static System.Type GetContainerEntity(this PropertyPath propertyPath, IModelInspector domainInspector) + { + PropertyPath analizing = propertyPath; + while (analizing.PreviousPath != null && !domainInspector.IsEntity(analizing.LocalMember.ReflectedType)) + { + analizing = analizing.PreviousPath; + } + return analizing.LocalMember.ReflectedType; + } + public static string ToColumnName(this PropertyPath propertyPath, string pathSeparator) { return propertyPath.ToString().Replace(".", pathSeparator); Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/ConventionModelMapperTests/ManyToManyInCollectionTableTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/ConventionModelMapperTests/ManyToManyInCollectionTableTests.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/ConventionModelMapperTests/ManyToManyInCollectionTableTests.cs 2011-04-12 22:59:26 UTC (rev 5682) @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.ConventionModelMapperTests +{ + public class ManyToManyInCollectionTableTests + { + private class MyClass + { + public int Id { get; set; } + public ICollection<MyBidirect> MyBidirects { get; set; } + public IDictionary<MyBidirect, string> MapKey { get; set; } + public IDictionary<string, MyBidirect> MapValue { get; set; } + public MyComponent MyComponent { get; set; } + } + + private class MyComponent + { + public ICollection<MyBidirect> MyBidirects { get; set; } + } + + private class MyBidirect + { + public int Id { get; set; } + public ICollection<MyClass> MyClasses { get; set; } + } + + private HbmMapping GetModelMapping() + { + var mapper = new ConventionModelMapper(); + mapper.Class<MyClass>(map => + { + map.Bag(mc => mc.MyBidirects, c => { }, rel => rel.ManyToMany()); + map.Map(mc => mc.MapKey, c => { }, mk => mk.ManyToMany(), mv => { }); + map.Map(mc => mc.MapValue, c => { }, mk => { }, mv => mv.ManyToMany()); + }); + mapper.Class<MyBidirect>(map => + { + map.Bag(mc => mc.MyClasses, c => { }, rel => rel.ManyToMany()); + }); + mapper.Component<MyComponent>(map => + { + map.Bag(mc => mc.MyBidirects, c => { }, rel => rel.ManyToMany()); + }); + return mapper.CompileMappingFor(new[] {typeof (MyClass), typeof (MyBidirect)}); + } + + [Test] + public void WhenManyToManyCollectionThenApplyTableAlphabetical() + { + HbmMapping mapping = GetModelMapping(); + + var hbmMyClass = mapping.RootClasses.Where(x => x.Name.Contains("MyClass")).Single(); + var hbmMyBidirect = mapping.RootClasses.Where(x => x.Name.Contains("MyBidirect")).Single(); + + var hbmBagMyClass = hbmMyClass.Properties.Where(p => p.Name == "MyBidirects").OfType<HbmBag>().Single(); + var hbmBagMyBidirect = hbmMyBidirect.Properties.Where(p => p.Name == "MyClasses").OfType<HbmBag>().Single(); + + hbmBagMyClass.Table.Should().Be("MyBidirectToMyClass"); + hbmBagMyBidirect.Table.Should().Be(hbmBagMyClass.Table); + } + + [Test] + public void WhenRelationDeclaredAsManyToManyForDictionaryKeyThenNoMatch() + { + HbmMapping mapping = GetModelMapping(); + + var hbmMyClass = mapping.RootClasses.Where(x => x.Name.Contains("MyClass")).Single(); + var hbmMapKey = hbmMyClass.Properties.Where(p => p.Name == "MapKey").OfType<HbmMap>().Single(); + + hbmMapKey.Table.Should().Be.Null(); + } + + [Test] + public void WhenRelationDeclaredAsManyToManyForDictionaryValueThenMatch() + { + HbmMapping mapping = GetModelMapping(); + + var hbmMyClass = mapping.RootClasses.Where(x => x.Name.Contains("MyClass")).Single(); + var hbmMapValue = hbmMyClass.Properties.Where(p => p.Name == "MapValue").OfType<HbmMap>().Single(); + + hbmMapValue.Table.Should().Be("MyBidirectToMyClass"); + } + + [Test] + public void WhenManyToManyCollectionInsideComponentThenApplyFromEntityToEntity() + { + HbmMapping mapping = GetModelMapping(); + + var hbmMyClass = mapping.RootClasses.Where(x => x.Name.Contains("MyClass")).Single(); + var hbmMyComponent = hbmMyClass.Properties.Where(p => p.Name == "MyComponent").OfType<HbmComponent>().Single(); + var hbmBagMyClass = hbmMyComponent.Properties.Where(p => p.Name == "MyBidirects").OfType<HbmBag>().Single(); + + hbmBagMyClass.Table.Should().Be("MyBidirectToMyClass"); + } + } +} \ 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-12 19:16:13 UTC (rev 5681) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-12 22:59:26 UTC (rev 5682) @@ -512,6 +512,7 @@ <Compile Include="Logging\Log4NetLoggerTest.cs" /> <Compile Include="Logging\LoggerProviderTest.cs" /> <Compile Include="MappingByCode\ConventionModelMapperTests\JoinedSubclassKeyAsRootIdColumnTest.cs" /> + <Compile Include="MappingByCode\ConventionModelMapperTests\ManyToManyInCollectionTableTests.cs" /> <Compile Include="MappingByCode\ConventionModelMapperTests\PropertyColumnNameTests.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\BagOfNestedComponentsWithParentTest.cs" /> <Compile Include="MappingByCode\ExpliticMappingTests\ClassWithComponentsTest.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |