|
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.
|