Info: There is a group object. Users can be invited to groups. There are two types of group invitations: external and internal. All invites are stored in single table using discriminator. The group object knows only about internal invites.
Problem In the Invite table there are two records. One for internal and one for external. If I load the group I will see both invites even the collection is of type InternalInvite. .
SELECT internalin0_.Group_id as Group3_1_,
internalin0_.Id as Id1_,
internalin0_.Id as Id0_0_,
internalin0_.Group_id as Group3_0_0_,
internalin0_.User_id as User5_0_0_
FROM [AbstractInvite] internalin0_ WHERE internalin0_.Group_id = 'be60b160-659e-4157-b033-9f9e00e346c7'
When I change the ISet collection type to AbstractInvite it will load all invites with the correct type.
Question How can I map the collection property to only InternalInvites?
I will try to minimize the code as much as I can.
The group and the group mapping:
public class Group
{
public Group()
{
InternalInvitations = new HashedSet<InternalInvite>();
}
public virtual Guid Id { get; set; }
public virtual ISet<InternalInvite> InternalInvitations { get; set; }
}
public class GroupMap : ClassMap<Group>
{
public GroupMap()
{
Id(x => x.Id);
HasMany(x => x.InternalInvitations).Inverse();
}
}
The external and internal invite + mappings:
public abstract class AbstractInvite
{
public virtual Guid Id { get; set; }
public virtual Group Group { get; set; }
}
public class ExternalInvite : AbstractInvite
{
public virtual string Name { get; set; }
}
public class InternalInvite : AbstractInvite
{
public virtual User User { get; set; }
}
public class AbstractInviteMap : ClassMap<AbstractInvite>
{
public AbstractInviteMap()
{
Id(x => x.Id);
References(x => x.Group);
DiscriminateSubClassesOnColumn("type");
}
}
public class ExternalInviteMap : SubclassMap<ExternalInvite>
{
public ExternalInviteMap()
{
Map(x => x.Name);
}
}
public class InternalInviteMap : SubclassMap<InternalInvite>
{
public InternalInviteMap()
{
References(x => x.User);
}
}
I will answer to myself.
I was able to achieve my goal with the code below:
public class AbstractInviteMap : ClassMap<AbstractInvite>
{
public AbstractInviteMap()
{
Id(x => x.Id);
References(x => x.Group);
DiscriminateSubClassesOnColumn("type").AlwaysSelectWithValue();
}
}
Reference: Discriminator in NHibernate documentation. Focus on 'force' option.