Reputation: 20191
I have this case that can't really get to work. Basically, I have abstract class User
and extended classes Admin
, Teacher
and LabEmployee
. Here are my mappings:
<class name="User" table="users" dynamic-update="true" dynamic-insert="true" select-before-update="false">
<id name="Id">
<column name="id" sql-type="bigint"/>
<generator class="identity"/>
</id>
<discriminator column="user_type" type="String"/>
...
some irrelevant properties (username, password, email etc.)
...
<subclass name="Admin" discriminator-value="ADMIN"/>
<subclass name="LabEmloyee" discriminator-value="LABEMPLOYEE"/>
<subclass name="Teacher" discriminator-value="TEACHER"/>
</class>
Now, I would really like to use this Enum
public enum UserType
{
ADMIN, LABEMPLOYEE, TEACHER
}
I understand that Nhibernate by default maps enums to integers so ADMIN would be "0", LABEMPLOYEE would be "1" and TEACHER would be "2". I tried following this post:
... and defined UserTypeWrapper:
public class UserTypeWrapper: NHibernate.Type.EnumStringType
{
public UserTypeWrapper()
: base(typeof(User.UserType))
{
}
}
... but it assumes that enum is not discriminator, that is, I can't set discriminator type as UserTypeWrapper
as NHibernate throws MappingException "Could not determine type for: UserTypeWrapper".
Does anyone know how to achieve this?
Any help would be greatly appreciated! Thanks!
Upvotes: 3
Views: 2354
Reputation: 30813
discriminator value is nowhere seen in the classes therefor you dont need any usertype to convert from db to property. in the hbm you also cant use the enum, you have to write the value directly in discriminator-value=""
. What you want is probably:
abstract class User
{
public virtual UserType Type { get; protected set;}
}
class Teacher : User
{
public Teacher()
{
Type = UserType.Teacher;
}
}
class LabEmployee : User
{
public LabEmployee()
{
Type = UserType.LabEmployee;
}
}
switch(someuser.Type)
or using a convention
abstract class User
{
public virtual UserType Type { get; protected set;}
public User()
{
Type = Enum.Parse(typeof(UserType), this.GetType().Name);
}
}
and to use a convention for the value in the mapping as well (Fluent NHibernate convention to specify the discriminator value)
public class DiscriminatorValueConvention : ISubclassConvention
{
public void Apply(ISubclassInstance instance)
{
instance.DiscriminatorValue(instance.EntityType.Name);
}
}
Upvotes: 5