Skip to content

Commit 0600443

Browse files
Radim-Kohlerhazzik
authored andcommitted
NH-3198 - Add support for Dynamic Component inside Join by Mapping By Code
1 parent 091fa6b commit 0600443

File tree

4 files changed

+208
-1
lines changed

4 files changed

+208
-1
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
using System;
2+
using System.Collections;
3+
using System.Linq;
4+
using NHibernate.Cfg.MappingSchema;
5+
using NHibernate.Mapping.ByCode;
6+
using NHibernate.Mapping.ByCode.Conformist;
7+
using NUnit.Framework;
8+
9+
namespace NHibernate.Test.MappingByCode.ExplicitMappingTests
10+
{
11+
public class JoinDynamicComponentTests
12+
{
13+
public class MyClass
14+
{
15+
public virtual int Code { get; set; }
16+
public virtual string JoinedName { get; set; }
17+
public virtual MyOther Relation { get; set; }
18+
public virtual MyOther JoinedRelation { get; set; }
19+
public virtual IDictionary Attributes { get; set; }
20+
public virtual IDictionary JoinedAttributes { get; set; }
21+
}
22+
23+
public class MyOther
24+
{
25+
public int Id { get; set; }
26+
}
27+
28+
public class MyClassMap : ClassMapping<MyClass>
29+
{
30+
public MyClassMap()
31+
{
32+
// basic table related properties
33+
ManyToOne(x => x.Relation);
34+
Component(p => p.Attributes,
35+
new
36+
{
37+
IsVisible = false,
38+
Hash = default(Guid),
39+
Reference = default(MyOther)
40+
},
41+
m =>
42+
{
43+
m.Property(p => p.IsVisible);
44+
m.Property(p => p.Hash);
45+
m.ManyToOne(p => p.Reference);
46+
});
47+
Property(x => x.Code);
48+
49+
// joined table stuff
50+
Join("JoinedAttributes", x =>
51+
{
52+
x.Property(p => p.JoinedName);
53+
x.Component(p => p.JoinedAttributes,
54+
new
55+
{
56+
OtherReference = default(MyOther),
57+
Description = string.Empty,
58+
Age = 0,
59+
},
60+
m =>
61+
{
62+
m.ManyToOne(p => p.OtherReference);
63+
m.Property(p => p.Description);
64+
m.Property(p => p.Age);
65+
});
66+
x.ManyToOne(p => p.JoinedRelation);
67+
});
68+
}
69+
}
70+
71+
private static HbmClass CompileClassMapping()
72+
{
73+
var mapper = new ModelMapper();
74+
mapper.AddMapping(typeof(MyClassMap));
75+
76+
var hbmMapping = mapper.CompileMappingFor(new[] { typeof(MyClass) });
77+
var hbmClass = hbmMapping.RootClasses[0];
78+
79+
return hbmClass;
80+
}
81+
82+
[Test]
83+
public void WhenPropertyIsMappedOnRootThenItBelongsToRootTable()
84+
{
85+
// <class name="MyClass"">
86+
var hbmClass = CompileClassMapping();
87+
Assert.That(hbmClass, Is.Not.Null);
88+
89+
var rootProperties = hbmClass.Properties;
90+
// <property name="Code"
91+
var hbmPropCode = rootProperties
92+
.FirstOrDefault(p => p.Name == "Code");
93+
94+
Assert.That(hbmPropCode, Is.Not.Null);
95+
Assert.That(hbmPropCode, Is.TypeOf<HbmProperty>());
96+
}
97+
98+
[Test]
99+
public void WhenDynamicComponentIsMappedOnRootThenItBelongsToRootTable()
100+
{
101+
// <class name="MyClass"">
102+
var hbmClass = CompileClassMapping();
103+
Assert.That(hbmClass, Is.Not.Null);
104+
105+
var rootProperties = hbmClass.Properties;
106+
// <dynamic-component name="Attributes"
107+
var hbmPropAttributes = rootProperties
108+
.FirstOrDefault(p => p.Name == "Attributes")
109+
;
110+
111+
Assert.That(hbmPropAttributes, Is.Not.Null);
112+
Assert.That(hbmPropAttributes, Is.TypeOf<HbmDynamicComponent>());
113+
}
114+
115+
[Test]
116+
public void WhenRelationIsMappedOnRootThenItBelongsToRootTable()
117+
{
118+
// <class name="MyClass"">
119+
var hbmClass = CompileClassMapping();
120+
Assert.That(hbmClass, Is.Not.Null);
121+
122+
var rootProperties = hbmClass.Properties;
123+
// <many-to-one name="Relation"
124+
var hbmPropRelation = rootProperties
125+
.FirstOrDefault(p => p.Name == "Relation");
126+
127+
Assert.That(hbmPropRelation, Is.Not.Null);
128+
Assert.That(hbmPropRelation, Is.TypeOf<HbmManyToOne>());
129+
}
130+
131+
[Test]
132+
public void WhenJoinedPropertyIsMappedOnJoinThenItBelongsToJoinTable()
133+
{
134+
// <class name="MyClass"">
135+
var hbmClass = CompileClassMapping();
136+
Assert.That(hbmClass, Is.Not.Null);
137+
138+
// <join table="JoinedAttributes">
139+
var hbmJoined = hbmClass.Joins.FirstOrDefault();
140+
Assert.That(hbmJoined, Is.Not.Null);
141+
142+
var rootProperties = hbmJoined.Properties;
143+
// <join table="JoinedAttributes">
144+
// <dynamic-component name="Attributes"
145+
var hbmPropJoinedName = rootProperties
146+
.FirstOrDefault(p => p.Name == "JoinedName");
147+
148+
Assert.That(hbmPropJoinedName, Is.Not.Null);
149+
Assert.That(hbmPropJoinedName, Is.TypeOf<HbmProperty>());
150+
}
151+
152+
[Test]
153+
public void WhenJoinedRelationIsMappedOnJoinThenItBelongsToJoinTable()
154+
{
155+
// <class name="MyClass"">
156+
var hbmClass = CompileClassMapping();
157+
Assert.That(hbmClass, Is.Not.Null);
158+
159+
// <join table="JoinedAttributes">
160+
var hbmJoined = hbmClass.Joins.FirstOrDefault();
161+
Assert.That(hbmJoined, Is.Not.Null);
162+
163+
var rootProperties = hbmJoined.Properties;
164+
// <join table="JoinedAttributes">
165+
// <many-to-one name="JoinedRelation"
166+
var hbmPropJoinedRelation = rootProperties
167+
.FirstOrDefault(p => p.Name == "JoinedRelation");
168+
169+
Assert.That(hbmPropJoinedRelation, Is.Not.Null);
170+
Assert.That(hbmPropJoinedRelation, Is.TypeOf<HbmManyToOne>());
171+
}
172+
173+
[Test]
174+
public void WhenJoinedDynamicComponentIsMappedOnJoinThenItBelongsToJoinTable()
175+
{
176+
// <class name="MyClass"">
177+
var hbmClass = CompileClassMapping();
178+
Assert.That(hbmClass, Is.Not.Null);
179+
180+
// <join table="JoinedAttributes">
181+
var hbmJoined = hbmClass.Joins.FirstOrDefault();
182+
Assert.That(hbmJoined, Is.Not.Null);
183+
184+
var rootProperties = hbmJoined.Properties;
185+
// <join table="JoinedAttributes">
186+
// <dynamic-component name="JoinedAttributes">
187+
var hbmPropJoinedAttributes = rootProperties
188+
.FirstOrDefault(p => p.Name == "JoinedAttributes");
189+
190+
Assert.That(hbmPropJoinedAttributes, Is.Not.Null);
191+
Assert.That(hbmPropJoinedAttributes, Is.TypeOf<HbmDynamicComponent>());
192+
}
193+
}
194+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,7 @@
604604
<Compile Include="MappingByCode\ExplicitMappingTests\DynamicComponentMappingTests.cs" />
605605
<Compile Include="MappingByCode\ExplicitMappingTests\IdBagMappingTest.cs" />
606606
<Compile Include="MappingByCode\ExplicitMappingTests\MappingOfInternalMembersOnRootEntity.cs" />
607+
<Compile Include="MappingByCode\ExplicitMappingTests\JoinDynamicComponentTests.cs" />
607608
<Compile Include="MappingByCode\ExplicitMappingTests\MappingOfPrivateMembersOnRootEntity.cs" />
608609
<Compile Include="MappingByCode\ExplicitMappingTests\NaturalIdTests.cs" />
609610
<Compile Include="MappingByCode\ExplicitMappingTests\NestedComponetsTests.cs" />

src/NHibernate/Mapping/ByCode/Impl/CustomizersImpl/JoinCustomizer.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ protected override void RegisterComponentMapping<TComponent>(Expression<Func<TEn
132132
base.RegisterComponentMapping(property, mapping);
133133
}
134134

135+
protected override void RegisterDynamicComponentMapping<TComponent>(Expression<Func<TEntity, System.Collections.IDictionary>> property
136+
, Action<IDynamicComponentMapper<TComponent>> mapping)
137+
{
138+
MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(property);
139+
ExplicitDeclarationsHolder.AddAsPropertySplit(new SplitDefinition(typeof(TEntity), splitGroupId, member));
140+
base.RegisterDynamicComponentMapping(property, mapping);
141+
}
142+
135143
protected override void RegisterManyToOneMapping<TProperty>(Expression<Func<TEntity, TProperty>> property, Action<IManyToOneMapper> mapping)
136144
{
137145
MemberInfo member = TypeExtensions.DecodeMemberAccessExpression(property);

src/NHibernate/Mapping/ByCode/ModelMapper.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,10 @@ private void MapSplitProperties(System.Type propertiesContainerType, IEnumerable
866866
{
867867
MapComponent(member, memberPath, propertyType, propertiesContainer, propertiesContainerType);
868868
}
869+
else if (modelInspector.IsDynamicComponent(member))
870+
{
871+
MapDynamicComponent(member, memberPath, propertyType, propertiesContainer);
872+
}
869873
else
870874
{
871875
MapProperty(member, memberPath, propertiesContainer);
@@ -1028,7 +1032,7 @@ private void MapProperties(System.Type propertiesContainerType, IEnumerable<Memb
10281032
}
10291033
}
10301034

1031-
private void MapDynamicComponent(MemberInfo member, PropertyPath memberPath, System.Type propertyType, IPropertyContainerMapper propertiesContainer)
1035+
private void MapDynamicComponent(MemberInfo member, PropertyPath memberPath, System.Type propertyType, IBasePlainPropertyContainerMapper propertiesContainer)
10321036
{
10331037
propertiesContainer.Component(member, (IDynamicComponentMapper componentMapper) =>
10341038
{

0 commit comments

Comments
 (0)