我有这种实体关系。

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; }
}

请注意,UserGroup是基类,并且我有一些派生类,这些派生类由UserGroup.GroupType区分。我正在使用“每类单个表”层次结构继承映射策略。

流利的NHibernate映射:
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();
    }
}

,这是我想要实现的:
我也想使UserGroupMember也成为基类,并在UserGroup.GroupType鉴别符上进行鉴别。这可能吗?

用另一种表达这个问题的方式,如果我可以添加以下行,那将是很好的:
DiscriminateSubClassesOnColumn("UserGroup.GroupType");

进入UserGroupMemberMap

最佳答案

一,我们不能使用DiscriminateSubClassesOnColumn("UserGroup.GroupType");
在许多其他好的原因中,discriminator由NHiberante管理。这意味着,在创建任何子对象期间,必须很容易使用INSERTable这样的值。并且不能与包含的外部表/引用一起使用...

二。但是在这些情况下,我们可以使采取另一种方式。让我们查看文档(在xml映射中,但fluent只是其顶部的包装器)

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)
/>



对我们来说真正有趣且有用的是(4)(5)。我们可以简单地将鉴别符设置为只读(不插入),并使用公式
<discriminator insert="false"
 formula="(SELECT ug.GroupType FROM UserGroup ug WHERE ug.UserGroupId = UserGroupId)"/>

注意:最后一个UserGroupId将被NHibernate视为当前表中的一列。这是必不可少的,很棒的...

好的。现在,我们的<discriminator>确实返回了正确的值。在创建新实例的过程中,它也不会插入值。我们只需要确保将分配正确的UserGroup引用,并带有所需的Type ...

流利性应该很明显,但是要确保:
DiscriminateSubClassesOnColumn(null)
    .Formula("(SELECT...")
    .ReadOnly()
    ;

关于c# - 如何使用Fluent NHibernate区分父级关系的列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26372382/

10-10 11:53