How can I use Fluent NHibernate to discriminate in a parent column

I have this entity relationship.

public abstract class UserGroup { public virtual int UserGroupId { get; set; } public virtual int GroupType { get; set; } public virtual string GroupName { get; set; } public virtual IList<UserGroupMember> GroupMembers { get; set; } } public class UserGroupMember { public virtual int UserGroupMemberId { get; set; } public virtual User User { get; set; } public virtual UserGroup UserGroup { get; set; } } 

Note that UserGroup is a base class and that I have several derived classes that differ UserGroup.GroupType . I use a strategy for matching the inheritance of a single table hierarchy to a class.

Free NHibernate Mappings:

 public class UserGroupMap : BaseClassMap<UserGroup> { public UserGroupMap() { Table("UserGroup"); Id(x => x.UserGroupId); DiscriminateSubClassesOnColumn("GroupType"); Map(x => x.GroupName); HasMany(x => x.GroupMembers) .KeyColumn("UserGroupId") .Cascade.AllDeleteOrphan() .Inverse(); } } public class UserGroupMemberMap: BaseClassMap<UserGroupMember> { public UserGroupMemberMap() { Table("UserGroupMember"); Id(x => x.UserGroupMemberId); References(x => x.User, "UserId") .Cascade.SaveUpdate(); References(x => x.UserGroup, "UserGroupId") .Cascade.SaveUpdate(); } } 

This is what I want to achieve:
I would also like to make UserGroupMember a base class and recognize it on the discriminator of UserGroup.GroupType . Is it possible?

Another way of wording this question would be great if I could add the following line:

 DiscriminateSubClassesOnColumn("UserGroup.GroupType"); 

In UserGroupMemberMap

+5
source share
1 answer

I. We cannot use DiscriminateSubClassesOnColumn("UserGroup.GroupType");

Among many other good reasons, discriminator managed by NHiberante. This means that such a value should be easily INSERTable during the creation of any child object. And will not work with external tables / links included ...

II. But in these scenarios, we can go a different way. Let me wrap up the documentation (in xml mapping, but fluent - just a wrapper on top of it)

5.1.6. Discriminator

 <discriminator column="discriminator_column" (1) type="discriminator_type" (2) force="true|false" (3) insert="true|false" (4) formula="arbitrary SQL expression" (5) /> 

(1) column (optional - the default for the class) is the name of the discriminator column.
(2) a type (optional - default is String) a name that indicates the type of NHibernate
(3) force (optional - default is false) NHibernate "force" to specify valid discriminator values ​​even when retrieving all instances of the root class.
(4) insert (optional - default is true) set this to false if the discriminator column is also part of the associated composite identifier.
(5) formula (optional) an arbitrary SQL expression that is executed when the type needs to be evaluated. Detects content discrimination.

What is really very interesting and useful for us is (4) and (5) . We can simply set the discriminator as readonly (without insertion) and use the formula .

 <discriminator insert="false" formula="(SELECT ug.GroupType FROM UserGroup ug WHERE ug.UserGroupId = UserGroupId)"/> 

NOTE. The last UserGroupId will display NHibernate as a column in the current table. What is necessary and surprising ...

Good. Now our <discriminator> returns the correct value. It also does not insert a value when creating a new instance. We need only to be sure that the correct UserGroup link will be assigned, with the required type ...

Free should be obvious, but of course:

 DiscriminateSubClassesOnColumn(null) .Formula("(SELECT...") .ReadOnly() ; 
+5
source

Source: https://habr.com/ru/post/1204687/


All Articles