Skip to content

Commit 307ebe6

Browse files
committed
Customizers with mapping of not visible members
SVN: trunk@5790
1 parent a3fef76 commit 307ebe6

File tree

5 files changed

+523
-57
lines changed

5 files changed

+523
-57
lines changed
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using NHibernate.Cfg.MappingSchema;
6+
using NHibernate.Mapping.ByCode;
7+
using NUnit.Framework;
8+
using SharpTestsEx;
9+
10+
namespace NHibernate.Test.MappingByCode.ExpliticMappingTests
11+
{
12+
public class AllPropertiesRegistrationTests
13+
{
14+
private class MyClass
15+
{
16+
public int Id { get; set; }
17+
private int simple;
18+
public int Simple
19+
{
20+
get { return simple; }
21+
set { simple = value; }
22+
}
23+
24+
private IList<string> complexType;
25+
public IList<string> ComplexType
26+
{
27+
get { return complexType; }
28+
set { complexType = value; }
29+
}
30+
31+
private IEnumerable<string> bag;
32+
public IEnumerable<string> Bag
33+
{
34+
get { return bag; }
35+
set { bag = value; }
36+
}
37+
38+
private IEnumerable<MyCompo> idBag;
39+
public IEnumerable<MyCompo> IdBag
40+
{
41+
get { return idBag; }
42+
set { idBag = value; }
43+
}
44+
45+
private IEnumerable<string> set;
46+
public IEnumerable<string> Set
47+
{
48+
get { return set; }
49+
set { set = value; }
50+
}
51+
52+
private IEnumerable<string> list;
53+
public IEnumerable<string> List
54+
{
55+
get { return list; }
56+
set { list = value; }
57+
}
58+
59+
private IDictionary<int, string> map;
60+
public IDictionary<int, string> Map
61+
{
62+
get { return map; }
63+
set { map = value; }
64+
}
65+
66+
private MyCompo compo;
67+
public MyCompo Compo
68+
{
69+
get { return compo; }
70+
set { compo = value; }
71+
}
72+
73+
private Related oneToOne;
74+
public Related OneToOne
75+
{
76+
get { return oneToOne; }
77+
set { oneToOne = value; }
78+
}
79+
80+
private Related manyToOne;
81+
public Related ManyToOne
82+
{
83+
get { return manyToOne; }
84+
set { manyToOne = value; }
85+
}
86+
87+
private object any;
88+
public object Any
89+
{
90+
get { return any; }
91+
set { any = value; }
92+
}
93+
94+
private IDictionary dynamicCompo;
95+
public IDictionary DynamicCompo
96+
{
97+
get { return dynamicCompo; }
98+
set { dynamicCompo = value; }
99+
}
100+
}
101+
102+
private class MyCompo
103+
{
104+
public int Something { get; set; }
105+
}
106+
private class Related
107+
{
108+
public int Id { get; set; }
109+
}
110+
111+
private class Inherited:MyClass
112+
{
113+
114+
}
115+
116+
[Test]
117+
public void WhenMapPropertiesInTheInheritedThenMapInBase()
118+
{
119+
// without ignoring MyClass as root-class I will try to map all properties using the inherited class.
120+
// NH have to recognize the case and, following Object-Relational-Mapping rules, map those properties in the base class.
121+
// Where needed, using the SimpleModelInspector, the user can revert this behavior checking the DeclaringType and ReflectedType of the persistent member.
122+
var mapper = new ModelMapper();
123+
mapper.Class<MyClass>(mc => mc.Id(x => x.Id));
124+
mapper.JoinedSubclass<Inherited>(mc =>
125+
{
126+
mc.Property(x => x.Simple, map => map.Access(Accessor.Field));
127+
mc.Property(x => x.ComplexType, map => map.Access(Accessor.Field));
128+
mc.Bag(x => x.Bag, y => y.Access(Accessor.Field));
129+
mc.IdBag(x => x.IdBag, y => y.Access(Accessor.Field));
130+
mc.List(x => x.List, y => y.Access(Accessor.Field));
131+
mc.Set(x => x.Set, y => y.Access(Accessor.Field));
132+
mc.Map(x => x.Map, y => y.Access(Accessor.Field));
133+
mc.OneToOne(x => x.OneToOne, y => y.Access(Accessor.Field));
134+
mc.ManyToOne(x => x.ManyToOne, y => y.Access(Accessor.Field));
135+
mc.Any(x => x.Any, typeof(int), y => y.Access(Accessor.Field));
136+
mc.Component(x => x.DynamicCompo, new { A=2 }, y => y.Access(Accessor.Field));
137+
mc.Component(x => x.Compo, y =>
138+
{
139+
y.Access(Accessor.Field);
140+
y.Property(c => c.Something);
141+
});
142+
});
143+
var mappings = mapper.CompileMappingForAllExplicitAddedEntities();
144+
var hbmClass = mappings.RootClasses[0];
145+
var hbmJoinedSubclass = mappings.JoinedSubclasses[0];
146+
hbmClass.Properties.Select(p => p.Name).Should().Have.SameValuesAs("Simple", "ComplexType", "Bag", "IdBag", "List", "Set", "Map", "Compo", "OneToOne", "ManyToOne", "Any", "DynamicCompo");
147+
hbmClass.Properties.Select(p => p.Access).All(x=> x.Satisfy(access=> access.Contains("field.")));
148+
hbmJoinedSubclass.Properties.Should().Be.Empty();
149+
}
150+
151+
[Test]
152+
public void WhenMapPropertiesInTheBaseJumpedClassThenMapInInherited()
153+
{
154+
// ignoring MyClass and using Inherited, as root-class, I will try to map all properties using the base class.
155+
// NH have to recognize the case and map those properties in the inherited.
156+
var inspector = new SimpleModelInspector();
157+
inspector.IsRootEntity((type, declared) => type == typeof(Inherited));
158+
var mapper = new ModelMapper();
159+
mapper.Class<MyClass>(mc =>
160+
{
161+
mc.Id(x => x.Id);
162+
mc.Property(x => x.Simple, map => map.Access(Accessor.Field));
163+
mc.Property(x => x.ComplexType, map => map.Access(Accessor.Field));
164+
mc.Bag(x => x.Bag, y => y.Access(Accessor.Field));
165+
mc.IdBag(x => x.IdBag, y => y.Access(Accessor.Field));
166+
mc.List(x => x.List, y => y.Access(Accessor.Field));
167+
mc.Set(x => x.Set, y => y.Access(Accessor.Field));
168+
mc.Map(x => x.Map, y => y.Access(Accessor.Field));
169+
mc.OneToOne(x => x.OneToOne, y => y.Access(Accessor.Field));
170+
mc.ManyToOne(x => x.ManyToOne, y => y.Access(Accessor.Field));
171+
mc.Any(x => x.Any, typeof(int), y => y.Access(Accessor.Field));
172+
mc.Component(x => x.DynamicCompo, new { A = 2 }, y => y.Access(Accessor.Field));
173+
mc.Component(x => x.Compo, y =>
174+
{
175+
y.Access(Accessor.Field);
176+
y.Property(c => c.Something);
177+
});
178+
});
179+
mapper.Class<Inherited>(mc =>{});
180+
181+
var mappings = mapper.CompileMappingForAllExplicitAddedEntities();
182+
var hbmClass = mappings.RootClasses[0];
183+
mappings.JoinedSubclasses.Should().Be.Empty();
184+
hbmClass.Properties.Select(p => p.Name).Should().Have.SameValuesAs("Simple", "ComplexType", "Bag", "IdBag", "List", "Set", "Map", "Compo", "OneToOne", "ManyToOne", "Any", "DynamicCompo");
185+
hbmClass.Properties.Select(p => p.Access).All(x => x.Satisfy(access => access.Contains("field.")));
186+
}
187+
188+
[Test]
189+
public void WhenMapPropertiesInTheInheritedUsingMemberNameThenMapInBase()
190+
{
191+
// without ignoring MyClass as root-class I will try to map all properties using the inherited class.
192+
// NH have to recognize the case and, following Object-Relational-Mapping rules, map those properties in the base class.
193+
var mapper = new ModelMapper();
194+
mapper.Class<MyClass>(mc => mc.Id(x => x.Id));
195+
mapper.JoinedSubclass<Inherited>(mc =>
196+
{
197+
mc.Property("Simple", map => map.Access(Accessor.Field));
198+
mc.Property("ComplexType", map => map.Access(Accessor.Field));
199+
mc.Bag<string>("Bag", y => y.Access(Accessor.Field));
200+
mc.IdBag<MyCompo>("IdBag", y => y.Access(Accessor.Field));
201+
mc.List<string>("List", y => y.Access(Accessor.Field));
202+
mc.Set<string>("Set", y => y.Access(Accessor.Field));
203+
mc.Map<int, string>("Map", y => y.Access(Accessor.Field));
204+
mc.OneToOne<Related>("OneToOne", y => y.Access(Accessor.Field));
205+
mc.ManyToOne<Related>("ManyToOne", y => y.Access(Accessor.Field));
206+
mc.Any<object>("Any", typeof(int), y => y.Access(Accessor.Field));
207+
mc.Component("DynamicCompo", new { A = 2 }, y => y.Access(Accessor.Field));
208+
mc.Component<MyCompo>("Compo", y =>
209+
{
210+
y.Access(Accessor.Field);
211+
y.Property(c => c.Something);
212+
});
213+
});
214+
var mappings = mapper.CompileMappingForAllExplicitAddedEntities();
215+
var hbmClass = mappings.RootClasses[0];
216+
var hbmJoinedSubclass = mappings.JoinedSubclasses[0];
217+
hbmClass.Properties.Select(p => p.Name).Should().Have.SameValuesAs("Simple", "ComplexType", "Bag", "IdBag", "List", "Set", "Map", "Compo", "OneToOne", "ManyToOne", "Any", "DynamicCompo");
218+
hbmClass.Properties.Select(p => p.Access).All(x => x.Satisfy(access => access.Contains("field.")));
219+
hbmJoinedSubclass.Properties.Should().Be.Empty();
220+
}
221+
222+
[Test]
223+
public void WhenMapPropertiesInTheBaseJumpedClassUsingMemberNameThenMapInInherited()
224+
{
225+
// ignoring MyClass and using Inherited, as root-class, I will try to map all properties using the base class.
226+
// NH have to recognize the case and map those properties in the inherited.
227+
var inspector = new SimpleModelInspector();
228+
inspector.IsRootEntity((type, declared) => type == typeof (Inherited));
229+
var mapper = new ModelMapper();
230+
mapper.Class<MyClass>(mc =>
231+
{
232+
mc.Id(x => x.Id);
233+
mc.Property("Simple", map => map.Access(Accessor.Field));
234+
mc.Property("ComplexType", map => map.Access(Accessor.Field));
235+
mc.Bag<string>("Bag", y => y.Access(Accessor.Field));
236+
mc.IdBag<MyCompo>("IdBag", y => y.Access(Accessor.Field));
237+
mc.List<string>("List", y => y.Access(Accessor.Field));
238+
mc.Set<string>("Set", y => y.Access(Accessor.Field));
239+
mc.Map<int, string>("Map", y => y.Access(Accessor.Field));
240+
mc.OneToOne<Related>("OneToOne", y => y.Access(Accessor.Field));
241+
mc.ManyToOne<Related>("ManyToOne", y => y.Access(Accessor.Field));
242+
mc.Any<object>("Any", typeof (int), y => y.Access(Accessor.Field));
243+
mc.Component("DynamicCompo", new {A = 2}, y => y.Access(Accessor.Field));
244+
mc.Component<MyCompo>("Compo", y =>
245+
{
246+
y.Access(Accessor.Field);
247+
y.Property(c => c.Something);
248+
});
249+
});
250+
mapper.Class<Inherited>(mc => { });
251+
252+
HbmMapping mappings = mapper.CompileMappingForAllExplicitAddedEntities();
253+
HbmClass hbmClass = mappings.RootClasses[0];
254+
mappings.JoinedSubclasses.Should().Be.Empty();
255+
hbmClass.Properties.Select(p => p.Name).Should().Have.SameValuesAs("Simple", "ComplexType", "Bag", "IdBag", "List", "Set", "Map", "Compo", "OneToOne", "ManyToOne", "Any",
256+
"DynamicCompo");
257+
hbmClass.Properties.Select(p => p.Access).All(x => x.Satisfy(access => access.Contains("field.")));
258+
}
259+
}
260+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@
517517
<Compile Include="MappingByCode\ConventionModelMapperTests\PropertyToFieldAccessorTest.cs" />
518518
<Compile Include="MappingByCode\ConventionModelMapperTests\SafePoidTests.cs" />
519519
<Compile Include="MappingByCode\ConventionModelMapperTests\VersionOnBaseClassIntegrationTest.cs" />
520+
<Compile Include="MappingByCode\ExpliticMappingTests\AllPropertiesRegistrationTests.cs" />
520521
<Compile Include="MappingByCode\ExpliticMappingTests\BagOfNestedComponentsWithParentTest.cs" />
521522
<Compile Include="MappingByCode\ExpliticMappingTests\ClassWithComponentsTest.cs" />
522523
<Compile Include="MappingByCode\ExpliticMappingTests\ComponentAsIdTests.cs" />

src/NHibernate/Mapping/ByCode/IPlainPropertyContainerMapper.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,32 @@ public interface IMinimalPlainPropertyContainerMapper<TContainer>
3232

3333
void ManyToOne<TProperty>(Expression<Func<TContainer, TProperty>> property, Action<IManyToOneMapper> mapping) where TProperty : class;
3434
void ManyToOne<TProperty>(Expression<Func<TContainer, TProperty>> property) where TProperty : class;
35+
void ManyToOne<TProperty>(string notVidiblePropertyOrFieldName, Action<IManyToOneMapper> mapping) where TProperty : class;
3536
}
3637

3738
public interface IBasePlainPropertyContainerMapper<TContainer> : IMinimalPlainPropertyContainerMapper<TContainer>
3839
{
3940
void Component<TComponent>(Expression<Func<TContainer, TComponent>> property,
4041
Action<IComponentMapper<TComponent>> mapping) where TComponent : class;
4142
void Component<TComponent>(Expression<Func<TContainer, TComponent>> property) where TComponent : class;
42-
4343
void Component<TComponent>(Expression<Func<TContainer, IDictionary>> property,
4444
TComponent dynamicComponentTemplate,
4545
Action<IDynamicComponentMapper<TComponent>> mapping) where TComponent : class;
4646

47+
void Component<TComponent>(string notVidiblePropertyOrFieldName,
48+
Action<IComponentMapper<TComponent>> mapping) where TComponent : class;
49+
void Component<TComponent>(string notVidiblePropertyOrFieldName) where TComponent : class;
50+
void Component<TComponent>(string notVidiblePropertyOrFieldName,
51+
TComponent dynamicComponentTemplate,
52+
Action<IDynamicComponentMapper<TComponent>> mapping) where TComponent : class;
53+
4754
void Any<TProperty>(Expression<Func<TContainer, TProperty>> property, System.Type idTypeOfMetaType, Action<IAnyMapper> mapping) where TProperty : class;
55+
void Any<TProperty>(string notVidiblePropertyOrFieldName, System.Type idTypeOfMetaType, Action<IAnyMapper> mapping) where TProperty : class;
4856
}
4957

5058
public interface IPlainPropertyContainerMapper<TContainer> : IBasePlainPropertyContainerMapper<TContainer>
5159
{
5260
void OneToOne<TProperty>(Expression<Func<TContainer, TProperty>> property, Action<IOneToOneMapper> mapping) where TProperty : class;
61+
void OneToOne<TProperty>(string notVidiblePropertyOrFieldName, Action<IOneToOneMapper> mapping) where TProperty : class;
5362
}
5463
}

src/NHibernate/Mapping/ByCode/IPropertyContainerMapper.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,63 @@ void Set<TElement>(Expression<Func<TEntity, IEnumerable<TElement>>> property,
3333
Action<ICollectionElementRelation<TElement>> mapping);
3434
void Set<TElement>(Expression<Func<TEntity, IEnumerable<TElement>>> property,
3535
Action<ISetPropertiesMapper<TEntity, TElement>> collectionMapping);
36+
void Set<TElement>(string notVidiblePropertyOrFieldName,
37+
Action<ISetPropertiesMapper<TEntity, TElement>> collectionMapping,
38+
Action<ICollectionElementRelation<TElement>> mapping);
39+
void Set<TElement>(string notVidiblePropertyOrFieldName,
40+
Action<ISetPropertiesMapper<TEntity, TElement>> collectionMapping);
3641

3742
void Bag<TElement>(Expression<Func<TEntity, IEnumerable<TElement>>> property,
3843
Action<IBagPropertiesMapper<TEntity, TElement>> collectionMapping,
3944
Action<ICollectionElementRelation<TElement>> mapping);
4045
void Bag<TElement>(Expression<Func<TEntity, IEnumerable<TElement>>> property,
4146
Action<IBagPropertiesMapper<TEntity, TElement>> collectionMapping);
47+
void Bag<TElement>(string notVidiblePropertyOrFieldName,
48+
Action<IBagPropertiesMapper<TEntity, TElement>> collectionMapping,
49+
Action<ICollectionElementRelation<TElement>> mapping);
50+
void Bag<TElement>(string notVidiblePropertyOrFieldName,
51+
Action<IBagPropertiesMapper<TEntity, TElement>> collectionMapping);
4252

4353
void List<TElement>(Expression<Func<TEntity, IEnumerable<TElement>>> property,
4454
Action<IListPropertiesMapper<TEntity, TElement>> collectionMapping,
4555
Action<ICollectionElementRelation<TElement>> mapping);
4656
void List<TElement>(Expression<Func<TEntity, IEnumerable<TElement>>> property,
4757
Action<IListPropertiesMapper<TEntity, TElement>> collectionMapping);
58+
void List<TElement>(string notVidiblePropertyOrFieldName,
59+
Action<IListPropertiesMapper<TEntity, TElement>> collectionMapping,
60+
Action<ICollectionElementRelation<TElement>> mapping);
61+
void List<TElement>(string notVidiblePropertyOrFieldName,
62+
Action<IListPropertiesMapper<TEntity, TElement>> collectionMapping);
4863

4964
void Map<TKey, TElement>(Expression<Func<TEntity, IDictionary<TKey, TElement>>> property,
5065
Action<IMapPropertiesMapper<TEntity, TKey, TElement>> collectionMapping,
5166
Action<IMapKeyRelation<TKey>> keyMapping,
5267
Action<ICollectionElementRelation<TElement>> mapping);
53-
5468
void Map<TKey, TElement>(Expression<Func<TEntity, IDictionary<TKey, TElement>>> property,
5569
Action<IMapPropertiesMapper<TEntity, TKey, TElement>> collectionMapping,
5670
Action<ICollectionElementRelation<TElement>> mapping);
5771
void Map<TKey, TElement>(Expression<Func<TEntity, IDictionary<TKey, TElement>>> property,
5872
Action<IMapPropertiesMapper<TEntity, TKey, TElement>> collectionMapping);
73+
void Map<TKey, TElement>(string notVidiblePropertyOrFieldName,
74+
Action<IMapPropertiesMapper<TEntity, TKey, TElement>> collectionMapping,
75+
Action<IMapKeyRelation<TKey>> keyMapping,
76+
Action<ICollectionElementRelation<TElement>> mapping);
77+
void Map<TKey, TElement>(string notVidiblePropertyOrFieldName,
78+
Action<IMapPropertiesMapper<TEntity, TKey, TElement>> collectionMapping,
79+
Action<ICollectionElementRelation<TElement>> mapping);
80+
void Map<TKey, TElement>(string notVidiblePropertyOrFieldName,
81+
Action<IMapPropertiesMapper<TEntity, TKey, TElement>> collectionMapping);
5982

6083
void IdBag<TElement>(Expression<Func<TEntity, IEnumerable<TElement>>> property,
6184
Action<IIdBagPropertiesMapper<TEntity, TElement>> collectionMapping,
6285
Action<ICollectionElementRelation<TElement>> mapping);
6386
void IdBag<TElement>(Expression<Func<TEntity, IEnumerable<TElement>>> property,
6487
Action<IIdBagPropertiesMapper<TEntity, TElement>> collectionMapping);
88+
void IdBag<TElement>(string notVidiblePropertyOrFieldName,
89+
Action<IIdBagPropertiesMapper<TEntity, TElement>> collectionMapping,
90+
Action<ICollectionElementRelation<TElement>> mapping);
91+
void IdBag<TElement>(string notVidiblePropertyOrFieldName,
92+
Action<IIdBagPropertiesMapper<TEntity, TElement>> collectionMapping);
6593
}
6694

6795
public interface IPropertyContainerMapper<TEntity> : ICollectionPropertiesContainerMapper<TEntity>, IPlainPropertyContainerMapper<TEntity> where TEntity : class {}

0 commit comments

Comments
 (0)