Skip to content

Commit eb8c13f

Browse files
committed
Add ability to set extending entity name for subclasses in mapping by code
Fixes #2071
1 parent bf1e116 commit eb8c13f

File tree

11 files changed

+250
-6
lines changed

11 files changed

+250
-6
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.GH2071
4+
{
5+
public class Cat
6+
{
7+
public virtual Guid Id { get; set; }
8+
public virtual string Name { get; set; }
9+
}
10+
11+
public class DomesticCat : Cat
12+
{
13+
public virtual string OwnerName { get; set; }
14+
}
15+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using NHibernate.Cfg.MappingSchema;
2+
using NHibernate.Mapping.ByCode;
3+
using NUnit.Framework;
4+
5+
namespace NHibernate.Test.NHSpecificTest.GH2071
6+
{
7+
public abstract class FixtureBase : TestCaseMappingByCode
8+
{
9+
private object domesticCatId;
10+
11+
protected override HbmMapping GetMappings()
12+
{
13+
var mapper = new ModelMapper();
14+
mapper.Class<Cat>(rc =>
15+
{
16+
rc.EntityName("CatEntity");
17+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
18+
rc.Property(x => x.Name);
19+
});
20+
21+
MapSubclass(mapper);
22+
23+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
24+
}
25+
26+
protected abstract void MapSubclass(ModelMapper mapper);
27+
28+
protected override void OnSetUp()
29+
{
30+
using (var session = OpenSession())
31+
using (var transaction = session.BeginTransaction())
32+
{
33+
domesticCatId = session.Save(new DomesticCat {Name = "Tom", OwnerName = "Jerry"});
34+
35+
transaction.Commit();
36+
}
37+
}
38+
39+
protected override void OnTearDown()
40+
{
41+
using (var session = OpenSession())
42+
using (var transaction = session.BeginTransaction())
43+
{
44+
session.Delete("from System.Object");
45+
46+
transaction.Commit();
47+
}
48+
}
49+
50+
[Test]
51+
public void CanLoadDomesticCat()
52+
{
53+
using (var session = OpenSession())
54+
using (session.BeginTransaction())
55+
{
56+
var cat = session.Load<Cat>(domesticCatId);
57+
Assert.That(cat, Is.Not.Null);
58+
Assert.That(cat.Name, Is.EqualTo("Tom"));
59+
}
60+
}
61+
}
62+
63+
[TestFixture]
64+
public class SubclassFixture : FixtureBase
65+
{
66+
protected override void MapSubclass(ModelMapper mapper)
67+
{
68+
mapper.Subclass<DomesticCat>(
69+
rc =>
70+
{
71+
rc.Extends("CatEntity");
72+
rc.Property(x => x.OwnerName);
73+
});
74+
}
75+
}
76+
77+
[TestFixture]
78+
public class JoinedSubclassFixture : FixtureBase
79+
{
80+
protected override void MapSubclass(ModelMapper mapper)
81+
{
82+
mapper.JoinedSubclass<DomesticCat>(
83+
rc =>
84+
{
85+
rc.Extends("CatEntity");
86+
rc.Property(x => x.OwnerName);
87+
});
88+
}
89+
}
90+
91+
[TestFixture]
92+
public class UnionSubclassFixture : FixtureBase
93+
{
94+
protected override void MapSubclass(ModelMapper mapper)
95+
{
96+
mapper.UnionSubclass<DomesticCat>(
97+
rc =>
98+
{
99+
rc.Extends("CatEntity");
100+
rc.Property(x => x.OwnerName);
101+
});
102+
}
103+
}
104+
}

src/NHibernate/Mapping/ByCode/IJoinedSubclassMapper.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
using System;
2+
using NHibernate.Mapping.ByCode.Impl;
3+
using NHibernate.Mapping.ByCode.Impl.CustomizersImpl;
4+
using NHibernate.Util;
25

36
namespace NHibernate.Mapping.ByCode
47
{
@@ -29,4 +32,32 @@ public interface IJoinedSubclassAttributesMapper<TEntity> : IEntityAttributesMap
2932
}
3033

3134
public interface IJoinedSubclassMapper<TEntity> : IJoinedSubclassAttributesMapper<TEntity>, IPropertyContainerMapper<TEntity> where TEntity : class {}
32-
}
35+
36+
public static class JoinedSubclassAttributesMapperExtensions
37+
{
38+
//6.0 TODO: Merge to IJoinedSubclassAttributesMapper<TEntity>
39+
public static void Extends<TEntity>(this IJoinedSubclassAttributesMapper<TEntity> mapper, string entityOrClassName)
40+
where TEntity : class
41+
{
42+
switch (mapper)
43+
{
44+
case JoinedSubclassCustomizer<TEntity> jsc:
45+
jsc.Extends(entityOrClassName);
46+
break;
47+
case PropertyContainerCustomizer<TEntity> pcc:
48+
pcc.CustomizersHolder.AddCustomizer(
49+
typeof(TEntity),
50+
(IJoinedSubclassAttributesMapper m) => m.Extends(entityOrClassName));
51+
break;
52+
default:
53+
throw new ArgumentException($@"{mapper.GetType()} requires to extend {typeof(JoinedSubclassCustomizer<TEntity>).FullName} or {typeof(PropertyContainerCustomizer<TEntity>).FullName} to support Extends(entityOrClassName).");
54+
}
55+
}
56+
57+
//6.0 TODO: Merge to IJoinedSubclassAttributesMapper
58+
public static void Extends(this IJoinedSubclassAttributesMapper mapper, string entityOrClassName)
59+
{
60+
ReflectHelper.CastOrThrow<JoinedSubclassMapper>(mapper, "Extends(entityOrClassName)").Extends(entityOrClassName);
61+
}
62+
}
63+
}

src/NHibernate/Mapping/ByCode/ISubclassMapper.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
using System;
2+
using NHibernate.Mapping.ByCode.Impl;
3+
using NHibernate.Mapping.ByCode.Impl.CustomizersImpl;
4+
using NHibernate.Util;
25

36
namespace NHibernate.Mapping.ByCode
47
{
@@ -27,4 +30,32 @@ public interface ISubclassMapper<TEntity> : ISubclassAttributesMapper<TEntity>,
2730
{
2831
void Join(string splitGroupId, Action<IJoinMapper<TEntity>> splitMapping);
2932
}
30-
}
33+
34+
public static class SubclassAttributesMapperExtensions
35+
{
36+
//6.0 TODO: Merge to ISubclassAttributesMapper<TEntity>
37+
public static void Extends<TEntity>(this ISubclassAttributesMapper<TEntity> mapper, string entityOrClassName)
38+
where TEntity : class
39+
{
40+
switch (mapper)
41+
{
42+
case SubclassCustomizer<TEntity> sc:
43+
sc.Extends(entityOrClassName);
44+
break;
45+
case PropertyContainerCustomizer<TEntity> pcc:
46+
pcc.CustomizersHolder.AddCustomizer(
47+
typeof(TEntity),
48+
(ISubclassMapper m) => m.Extends(entityOrClassName));
49+
break;
50+
default:
51+
throw new ArgumentException($@"{mapper.GetType()} requires to extend {typeof(SubclassCustomizer<TEntity>).FullName} or {typeof(PropertyContainerCustomizer<TEntity>).FullName} to support Extends(entityOrClassName).");
52+
}
53+
}
54+
55+
//6.0 TODO: Merge to ISubclassAttributesMapper
56+
public static void Extends(this ISubclassAttributesMapper mapper, string entityOrClassName)
57+
{
58+
ReflectHelper.CastOrThrow<SubclassMapper>(mapper, "Extends(entityOrClassName)").Extends(entityOrClassName);
59+
}
60+
}
61+
}

src/NHibernate/Mapping/ByCode/IUnionSubclassMapper.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
using System;
2+
using NHibernate.Mapping.ByCode.Impl;
3+
using NHibernate.Mapping.ByCode.Impl.CustomizersImpl;
4+
using NHibernate.Util;
5+
16
namespace NHibernate.Mapping.ByCode
27
{
38
public interface IUnionSubclassAttributesMapper : IEntityAttributesMapper, IEntitySqlsMapper
@@ -21,4 +26,32 @@ public interface IUnionSubclassAttributesMapper<TEntity> : IEntityAttributesMapp
2126
}
2227

2328
public interface IUnionSubclassMapper<TEntity> : IUnionSubclassAttributesMapper<TEntity>, IPropertyContainerMapper<TEntity> where TEntity : class {}
24-
}
29+
30+
public static class UnionSubclassAttributesMapperExtensions
31+
{
32+
//6.0 TODO: Merge to IUnionSubclassAttributesMapper<TEntity>
33+
public static void Extends<TEntity>(this IUnionSubclassAttributesMapper<TEntity> mapper, string entityOrClassName)
34+
where TEntity : class
35+
{
36+
switch (mapper)
37+
{
38+
case UnionSubclassCustomizer<TEntity> usc:
39+
usc.Extends(entityOrClassName);
40+
break;
41+
case PropertyContainerCustomizer<TEntity> pcc:
42+
pcc.CustomizersHolder.AddCustomizer(
43+
typeof(TEntity),
44+
(IUnionSubclassAttributesMapper m) => m.Extends(entityOrClassName));
45+
break;
46+
default:
47+
throw new ArgumentException($@"{mapper.GetType()} requires to extend {typeof(UnionSubclassCustomizer<TEntity>).FullName} or {typeof(PropertyContainerCustomizer<TEntity>).FullName} to support Extends(entityOrClassName).");
48+
}
49+
}
50+
51+
//6.0 TODO: Merge to IUnionSubclassAttributesMapper
52+
public static void Extends(this IUnionSubclassAttributesMapper mapper, string entityOrClassName)
53+
{
54+
ReflectHelper.CastOrThrow<UnionSubclassMapper>(mapper, "Extends(entityOrClassName)").Extends(entityOrClassName);
55+
}
56+
}
57+
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ public void Extends(System.Type baseType)
116116
CustomizersHolder.AddCustomizer(typeof(TEntity), (IJoinedSubclassAttributesMapper m) => m.Extends(baseType));
117117
}
118118

119+
public void Extends(string entityOrClassName)
120+
{
121+
CustomizersHolder.AddCustomizer(typeof(TEntity), (IJoinedSubclassAttributesMapper m) => m.Extends(entityOrClassName));
122+
}
123+
119124
public void Abstract(bool isAbstract)
120125
{
121126
CustomizersHolder.AddCustomizer(typeof(TEntity), (IJoinedSubclassAttributesMapper m) => m.Abstract(isAbstract));
@@ -157,4 +162,4 @@ IModelExplicitDeclarationsHolder IConformistHoldersProvider.ExplicitDeclarations
157162

158163
#endregion
159164
}
160-
}
165+
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public void Extends(System.Type baseType)
2727
CustomizersHolder.AddCustomizer(typeof(TEntity), (ISubclassMapper m) => m.Extends(baseType));
2828
}
2929

30+
public void Extends(string entityOrClassName)
31+
{
32+
CustomizersHolder.AddCustomizer(typeof(TEntity), (ISubclassMapper m) => m.Extends(entityOrClassName));
33+
}
34+
3035
public void Abstract(bool isAbstract)
3136
{
3237
CustomizersHolder.AddCustomizer(typeof(TEntity), (ISubclassMapper m) => m.Abstract(isAbstract));
@@ -155,4 +160,4 @@ IModelExplicitDeclarationsHolder IConformistHoldersProvider.ExplicitDeclarations
155160

156161
#endregion
157162
}
158-
}
163+
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ public void Extends(System.Type baseType)
102102
CustomizersHolder.AddCustomizer(typeof(TEntity), (IUnionSubclassAttributesMapper m) => m.Extends(baseType));
103103
}
104104

105+
public void Extends(string entityOrClassName)
106+
{
107+
CustomizersHolder.AddCustomizer(typeof(TEntity), (IUnionSubclassAttributesMapper m) => m.Extends(entityOrClassName));
108+
}
109+
105110
public void Abstract(bool isAbstract)
106111
{
107112
CustomizersHolder.AddCustomizer(typeof(TEntity), (IUnionSubclassAttributesMapper m) => m.Abstract(isAbstract));
@@ -138,4 +143,4 @@ IModelExplicitDeclarationsHolder IConformistHoldersProvider.ExplicitDeclarations
138143

139144
#endregion
140145
}
141-
}
146+
}

src/NHibernate/Mapping/ByCode/Impl/JoinedSubclassMapper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ public void Extends(System.Type baseType)
189189
classMapping.extends = baseType.GetShortClassName(MapDoc);
190190
}
191191

192+
public void Extends(string entityOrClassName)
193+
{
194+
classMapping.extends = entityOrClassName ?? throw new ArgumentNullException(nameof(entityOrClassName));
195+
}
196+
192197
public void SchemaAction(SchemaAction action)
193198
{
194199
classMapping.schemaaction = action.ToSchemaActionString();

src/NHibernate/Mapping/ByCode/Impl/SubclassMapper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ public void Extends(System.Type baseType)
6363
}
6464
classMapping.extends = baseType.GetShortClassName(MapDoc);
6565
}
66+
67+
public void Extends(string entityOrClassName)
68+
{
69+
classMapping.extends = entityOrClassName ?? throw new ArgumentNullException(nameof(entityOrClassName));
70+
}
6671

6772
public void Join(string splitGroupId, Action<IJoinMapper> splitMapping)
6873
{

0 commit comments

Comments
 (0)