Skip to content

Commit 7f26f75

Browse files
committed
Propagate discriminated subclasses throught hierarchy
Fixes #222 +semver:fix
1 parent 55869b0 commit 7f26f75

File tree

4 files changed

+64
-50
lines changed

4 files changed

+64
-50
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using FluentNHibernate.Automapping;
2+
using FluentNHibernate.Automapping.TestFixtures.SuperTypes;
3+
using NUnit.Framework;
4+
5+
namespace FluentNHibernate.Testing.Automapping
6+
{
7+
[TestFixture]
8+
public class SubclassConventionTests
9+
{
10+
[Test]
11+
public void DefaultConventionsAreAppliedToDiscriminatedSubClasses()
12+
{
13+
var model = AutoMap.AssemblyOf<SuperType>()
14+
.Where(x => x.Namespace == typeof(SuperType).Namespace)
15+
.Override<SuperType>(m => m.DiscriminateSubClassesOnColumn("Discriminator"));
16+
17+
new AutoMappingTester<SuperType>(model)
18+
.Element("class/subclass[@name='" + typeof(ExampleClass).AssemblyQualifiedName + "']/many-to-one/column")
19+
.HasAttribute("name", "Parent_id");
20+
}
21+
22+
[Test]
23+
public void DiscriminatedSubtypePropagatesThroughHierarchy()
24+
{
25+
var model = AutoMap.AssemblyOf<Derived1>()
26+
.Where(x => x.Namespace == typeof(Derived1).Namespace)
27+
.Override<Derived1>(m => m.DiscriminateSubClassesOnColumn("Discriminator"));
28+
29+
new AutoMappingTester<Derived1>(model)
30+
.Element("class[@name = '" + typeof(Derived1).AssemblyQualifiedName + "']")
31+
.Exists()
32+
.Element("class/subclass[@name='" + typeof(SecondLevel).AssemblyQualifiedName + "']")
33+
.Exists()
34+
.Element("class/subclass/joined-subclass")
35+
.DoesntExist()
36+
.Element("class/subclass[@name='" + typeof(SecondLevel).AssemblyQualifiedName + "']/" +
37+
"subclass[@name='" + typeof(ThirdLevel).AssemblyQualifiedName + "']")
38+
.Exists()
39+
.Element("class/subclass[@name='" + typeof(SecondLevel).AssemblyQualifiedName + "']/" +
40+
"subclass[@name='" + typeof(ThirdLevel).AssemblyQualifiedName + "']/" +
41+
"subclass[@name='" + typeof(FourthLevel).AssemblyQualifiedName + "']")
42+
.Exists();
43+
}
44+
}
45+
}

src/FluentNHibernate.Testing/AutoMapping/TestFixtures.cs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,6 @@ public class ExampleInheritedClass : ExampleClass
446446
public int SomeNumber{ get; set; }
447447
}
448448

449-
450449
public class ExampleClass : SuperType
451450
{
452451
public virtual int ExampleClassId { get; set; }
@@ -524,27 +523,4 @@ public enum PublisherType
524523
Offline,
525524
Mixed
526525
}
527-
}
528-
529-
namespace FluentNHibernate.Automapping.TestFixtures.UnionChain
530-
{
531-
public class BaseUnionType
532-
{
533-
public int Id { get; set; }
534-
}
535-
536-
public class ChildUnionType : BaseUnionType
537-
{
538-
public int Value { get; set; }
539-
}
540-
541-
public class GrandChildUnionType : ChildUnionType
542-
{
543-
public string Name { get; set; }
544-
}
545-
546-
public class GreatGrandChildUnionType : GrandChildUnionType
547-
{
548-
}
549-
}
550-
526+
}
Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using FluentNHibernate.Automapping;
22
using FluentNHibernate.Automapping.TestFixtures.SuperTypes;
3-
using FluentNHibernate.Automapping.TestFixtures.UnionChain;
43
using NUnit.Framework;
54

65
namespace FluentNHibernate.Testing.Automapping
@@ -23,25 +22,24 @@ public void DefaultConventionsAreAppliedToUnionSubClasses()
2322
[Test]
2423
public void UnionSubtypePropagatesThroughHierarchy()
2524
{
26-
new AutoMappingTester<BaseUnionType>(
27-
AutoMap.AssemblyOf<BaseUnionType>()
28-
.Where(x => x.Namespace == typeof(BaseUnionType).Namespace)
29-
.Override<BaseUnionType>(m => m.UseUnionSubclassForInheritanceMapping()))
30-
.Element("class[@name = '" + typeof(BaseUnionType).AssemblyQualifiedName + "']")
25+
var model = AutoMap.AssemblyOf<Derived1>()
26+
.Where(x => x.Namespace == typeof(Derived1).Namespace)
27+
.Override<Derived1>(m => m.UseUnionSubclassForInheritanceMapping());
28+
29+
new AutoMappingTester<Derived1>(model)
30+
.Element("class[@name = '" + typeof(Derived1).AssemblyQualifiedName + "']")
3131
.Exists()
32-
.Element("class/union-subclass[@name='" + typeof(ChildUnionType).AssemblyQualifiedName + "']")
32+
.Element("class/union-subclass[@name='" + typeof(SecondLevel).AssemblyQualifiedName + "']")
3333
.Exists()
3434
.Element("class/union-subclass/joined-subclass")
3535
.DoesntExist()
36-
.Element("class/union-subclass[@name='" + typeof(ChildUnionType).AssemblyQualifiedName + "']/" +
37-
"union-subclass[@name='" + typeof(GrandChildUnionType).AssemblyQualifiedName + "']")
38-
.Exists()
39-
.Element("class/union-subclass[@name='" + typeof(ChildUnionType).AssemblyQualifiedName + "']/" +
40-
"union-subclass[@name='" + typeof(GrandChildUnionType).AssemblyQualifiedName + "']/" +
41-
"union-subclass[@name='" + typeof(GreatGrandChildUnionType).AssemblyQualifiedName + "']")
36+
.Element("class/union-subclass[@name='" + typeof(SecondLevel).AssemblyQualifiedName + "']/" +
37+
"union-subclass[@name='" + typeof(ThirdLevel).AssemblyQualifiedName + "']")
4238
.Exists()
43-
;
39+
.Element("class/union-subclass[@name='" + typeof(SecondLevel).AssemblyQualifiedName + "']/" +
40+
"union-subclass[@name='" + typeof(ThirdLevel).AssemblyQualifiedName + "']/" +
41+
"union-subclass[@name='" + typeof(FourthLevel).AssemblyQualifiedName + "']")
42+
.Exists();
4443
}
45-
4644
}
4745
}

src/FluentNHibernate/Automapping/AutoMapper.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,17 @@ private void MapInheritanceTree(Type classType, ClassMappingBase mapping, IList<
7979

8080
SubclassMapping subclassMapping;
8181
var tempSubClassMap = mapping as SubclassMapping;
82-
if(!tempIsNull && tempMapping.IsUnionSubclass)
82+
if(!tempIsNull && tempMapping.IsUnionSubclass || tempSubClassMap != null && tempSubClassMap.SubclassType == SubclassType.UnionSubclass)
8383
{
8484
subclassMapping = new SubclassMapping(SubclassType.UnionSubclass);
8585
subclassMapping.Set(x => x.Type, Layer.Defaults, inheritedClass.Type);
8686
}
87-
else if (tempSubClassMap != null && tempSubClassMap.SubclassType == SubclassType.UnionSubclass)
87+
else if (isDiscriminated || tempSubClassMap != null && tempSubClassMap.SubclassType == SubclassType.Subclass)
8888
{
89-
subclassMapping = new SubclassMapping(SubclassType.UnionSubclass);
89+
subclassMapping = new SubclassMapping(SubclassType.Subclass);
9090
subclassMapping.Set(x => x.Type, Layer.Defaults, inheritedClass.Type);
9191
}
92-
else if(!isDiscriminated)
92+
else
9393
{
9494
subclassMapping = new SubclassMapping(SubclassType.JoinedSubclass);
9595
subclassMapping.Set(x => x.Type, Layer.Defaults, inheritedClass.Type);
@@ -98,11 +98,6 @@ private void MapInheritanceTree(Type classType, ClassMappingBase mapping, IList<
9898
columnMapping.Set(x => x.Name, Layer.Defaults, mapping.Type.Name + "_id");
9999
subclassMapping.Key.AddColumn(Layer.Defaults, columnMapping);
100100
}
101-
else
102-
{
103-
subclassMapping = new SubclassMapping(SubclassType.Subclass);
104-
subclassMapping.Set(x => x.Type, Layer.Defaults, inheritedClass.Type);
105-
}
106101

107102
// track separate set of properties for each sub-tree within inheritance hierarchy
108103
var subclassMembers = new List<Member>(mappedMembers);
@@ -116,7 +111,7 @@ private void MapInheritanceTree(Type classType, ClassMappingBase mapping, IList<
116111

117112
static bool HasDiscriminator(ClassMappingBase mapping)
118113
{
119-
if (mapping is ClassMapping && ((ClassMapping)mapping).Discriminator != null)
114+
if (mapping is ClassMapping && ((ClassMapping) mapping).Discriminator != null)
120115
return true;
121116

122117
return false;

0 commit comments

Comments
 (0)