Skip to content

Commit 6f293a2

Browse files
committed
Merge pull request #249 from chester89/issue210
#210 - Multi-column IUserType fails in SubclassMap<>
2 parents 9b5e54a + c55bdc8 commit 6f293a2

File tree

2 files changed

+166
-2
lines changed

2 files changed

+166
-2
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Text;
7+
using FluentNHibernate.Mapping;
8+
using NHibernate;
9+
using NHibernate.SqlTypes;
10+
using NHibernate.UserTypes;
11+
using NUnit.Framework;
12+
13+
namespace FluentNHibernate.Testing.FluentInterfaceTests
14+
{
15+
[TestFixture]
16+
public class SubclassMapWithUserTypeTests
17+
{
18+
[Test]
19+
public void ShouldTakeIntoAccountAllColumnsOfAUserType()
20+
{
21+
var model = new PersistenceModel();
22+
23+
model.Add(new MediaMap());
24+
model.Add(new ImageMap());
25+
26+
var mappings = model.BuildMappings();
27+
var sb = new StringBuilder();
28+
model.WriteMappingsTo(new StringWriter(sb));
29+
30+
var subclassMapping = mappings.SelectMany(m => m.Classes)
31+
.FirstOrDefault(cm => cm.Subclasses.Any()).Subclasses.FirstOrDefault();
32+
33+
subclassMapping.Properties.SingleOrDefault(x => x.Name == "Contexts");
34+
}
35+
}
36+
37+
public class Media
38+
{
39+
public virtual Guid Id { get; protected set; }
40+
public virtual bool IsDeprecated { get; set; }
41+
public virtual DateTime Created { get; set; }
42+
public virtual DateTime Modified { get; set; }
43+
44+
}
45+
46+
public class MediaMap : ClassMap<Media>
47+
{
48+
public MediaMap()
49+
{
50+
Id(x => x.Id).Column("[Guid]").GeneratedBy.GuidComb();
51+
Map(x => x.IsDeprecated).Not.Nullable();
52+
Map(x => x.Created).Not.Nullable();
53+
Map(x => x.Modified).Not.Nullable();
54+
}
55+
}
56+
57+
public class Image : Media
58+
{
59+
private IList<string> contexts = new List<string>();
60+
61+
public virtual string Title { get; set; }
62+
public virtual string Description { get; set; }
63+
public virtual int Width { get; set; }
64+
public virtual int Height { get; set; }
65+
66+
public virtual IList<string> Contexts { get { return contexts; } }
67+
}
68+
69+
public class ImageMap : SubclassMap<Image>
70+
{
71+
public ImageMap()
72+
{
73+
Table("[ImageInfo]");
74+
KeyColumn("[Guid]");
75+
Map(x => x.Title).Length(100).Not.Nullable();
76+
Map(x => x.Description).Length(500).Nullable();
77+
Map(x => x.Width).Not.Nullable();
78+
Map(x => x.Height).Not.Nullable();
79+
Map(x => x.Contexts)
80+
.Access.CamelCaseField()
81+
.CustomType<ImageContextsUserType>()
82+
.Columns.Add(new[] { "IsIcon", "IsPromo", "IsWallpaper", "IsPlaceholder" })
83+
.Not.Nullable();
84+
}
85+
}
86+
87+
public class ImageContextsUserType : IUserType
88+
{
89+
public bool Equals(object x, object y)
90+
{
91+
throw new NotImplementedException();
92+
}
93+
94+
public int GetHashCode(object x)
95+
{
96+
throw new NotImplementedException();
97+
}
98+
99+
public object NullSafeGet(IDataReader rs, string[] names, object owner)
100+
{
101+
IList<string> contexts = new List<string>();
102+
103+
if ((bool)NHibernateUtil.Boolean.NullSafeGet(rs, names[0])) contexts.Add("Icon");
104+
if ((bool)NHibernateUtil.Boolean.NullSafeGet(rs, names[1])) contexts.Add("Promo");
105+
if ((bool)NHibernateUtil.Boolean.NullSafeGet(rs, names[2])) contexts.Add("Wallpaper");
106+
if ((bool)NHibernateUtil.Boolean.NullSafeGet(rs, names[3])) contexts.Add("Placeholder");
107+
108+
return contexts;
109+
}
110+
111+
public void NullSafeSet(IDbCommand cmd, object value, int index)
112+
{
113+
IList<string> contexts = value as IList<string>;
114+
115+
if (contexts != null)
116+
{
117+
NHibernateUtil.Boolean.NullSafeSet(cmd, contexts.Contains("Icon"), index);
118+
NHibernateUtil.Boolean.NullSafeSet(cmd, contexts.Contains("Promo"), index + 1);
119+
NHibernateUtil.Boolean.NullSafeSet(cmd, contexts.Contains("Wallpaper"), index + 2);
120+
NHibernateUtil.Boolean.NullSafeSet(cmd, contexts.Contains("Placeholder"), index + 3);
121+
}
122+
}
123+
124+
public object DeepCopy(object value)
125+
{
126+
throw new NotImplementedException();
127+
}
128+
129+
public object Replace(object original, object target, object owner)
130+
{
131+
throw new NotImplementedException();
132+
}
133+
134+
public object Assemble(object cached, object owner)
135+
{
136+
throw new NotImplementedException();
137+
}
138+
139+
public object Disassemble(object value)
140+
{
141+
throw new NotImplementedException();
142+
}
143+
144+
public Type ReturnedType
145+
{
146+
get { return typeof(IList<string>); }
147+
}
148+
public bool IsMutable
149+
{
150+
get { throw new NotImplementedException(); }
151+
}
152+
153+
public SqlType[] SqlTypes
154+
{
155+
get
156+
{
157+
return new[] {
158+
NHibernateUtil.Boolean.SqlType, NHibernateUtil.Boolean.SqlType,
159+
NHibernateUtil.Boolean.SqlType, NHibernateUtil.Boolean.SqlType };
160+
}
161+
}
162+
}
163+
}

src/FluentNHibernate.Testing/FluentNHibernate.Testing.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@
137137
<Compile Include="Fixtures\AutoMappingAlterations\AbstractOverride.cs" />
138138
<Compile Include="Fixtures\AutoMappingAlterations\AbstractOverrideImplementation.cs" />
139139
<Compile Include="Fixtures\AutoMappingAlterations\Model\Qux.cs" />
140-
<Compile Include="Cfg\Db\IngresConfigurationTester.cs" />
141-
<Compile Include="FluentInterfaceTests\TablePerHierarchyTests.cs" />
140+
<Compile Include="Cfg\Db\IngresConfigurationTester.cs" />
141+
<Compile Include="FluentInterfaceTests\SubclassMapWithUserTypeTests.cs" />
142+
<Compile Include="FluentInterfaceTests\TablePerHierarchyTests.cs" />
142143
<Compile Include="StubTypeSource.cs" />
143144
<Compile Include="AutoMapping\TestFixtures.cs" />
144145
<Compile Include="Cfg\Db\DB2ConfigurationTester.cs" />

0 commit comments

Comments
 (0)