简体   繁体   中英

Fluent NHibernate: One to One Mapping - reverse from primary column to a foreign key

I have a "Group" class and a "GroupSummaryLevel" class, codes are given below. There is a one-to-one relation between these entities in DB. I need the "GroupSummaryLevel" as a property in Groups class. It is supposed to be a very simple join like

(SELECT g.Id FROM GroupSummaryLevel g WHERE g.AcctGroup = GroupID)

Unfortunately, I wasn't able to figure this out how to do with NHibernate. The many answers I saw here is no help to me. I would appreaciate any inputs from the more experienced NHibernate users out there. Thanks in advance.

public class Group : DomainEntity
{
    public virtual string GroupId { get; set; }
    public virtual string GroupName { get; set; }
    public virtual GroupSummaryLevel GroupSummaryLevel { get; set; }
}

public class GroupSummaryLevel : DomainEntity
{
    public virtual int Id { get; set; }
    public virtual string AcctGroup { get; set; }
    public virtual GroupSummaryLevel Parent { get; set; }
    public virtual IList<GroupSummaryLevel> Children { get; set; }

    public GroupSummaryLevel()
    {
        Children = new List<GroupSummaryLevel>();
    }
}

The mapping I have done did not work so far. My mapping codes are as below:

    public GroupMap()
    {
        Table("Groups");
        LazyLoad();
        Id(x => x.GroupId).GeneratedBy.Assigned().Column("GroupID").CustomType<TrimmedString>();
        Map(x => x.GroupName).Column("GroupName").CustomType<TrimmedString>().Not.Nullable();

        HasOne(x => x.GroupSummaryLevel).Cascade.None().ForeignKey("AcctGroup");
    }
    public GroupSummaryLevelMap()
    {
        Table("GroupSummaryLevel");
        LazyLoad();
        Id(x => x.Id).GeneratedBy.Identity().Column("Id");
        Map(x => x.AcctGroup).Column("AcctGroup").CustomType<TrimmedString>().Not.Nullable();

        //References(x => x.Parent).Column("ParentId");
        //HasMany(x => x.Children).Cascade.All().KeyColumn("ParentId");
    }

Note: I also need to do a self-join for GroupSummaryLevel, and no success with that either. Any recommendations for that will also be appreciated :)

I would say, that your one-to-one is not driven by primary/foreign keys, but by property-ref . So the Group should map the summary by saying something like this:

...if you want to find related SummaryLevel , pass my <id> into column mapped as AcctGroup

public GroupMap()
{
    ...
    HasOne(x => x.GroupSummaryLevel)
        .Cascade.None()
        //.ForeignKey("AcctGroup")
        .PropertyRef(gsl => gsl.AcctGroup)
        ;
}
public GroupSummaryLevelMap()
{
    ...
    //References(x => x.Parent).Column("ParentId");
    //HasMany(x => x.Children).Cascade.All().KeyColumn("ParentId");
    References(x => x.Parent, "AcctGroup");
}

NOTEs for completeness, as discussed in comments:

In this scenario, when the "child" has reference to parent - it really calls for one-to-many / .HasMany() mapping.

The down side is, that child is represented as a colleciton of children: IList<GroupSummaryLevel> . It is not as straighforward to use, but we can create some virtual property, returning the .FirstOrDefault() . The benefit we get - is lazy loading (not in place with one-to-one) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM