FluentNhibernate many-to-many and Inverse()

Go To StackoverFlow.com

3

I have the following database tables defined:

Club: Id, Name

Member: Id, Name

ClubMember: ClubId, MemberId

I have the following entity Classes defined:

    public class Club() {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual IList<Member> Members { get; set; }
    }

    public class Member() {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual IList<Club> Clubs { get; set; }
    }

I have the following overrides defined:

    public class MemberOverride : IAutoMappingOverride<Member>
    {
        public void Override(AutoMapping<Member> mapping_)
        {
            mapping_
                .HasManyToMany(x_ => x_.Clubs)
                .ParentKeyColumn("MemberId")
                .ChildKeyColumn("ClubId")
                .Cascade.All()
                .Table("ClubMembers");
        }
    }

    public class ClubOverride : IAutoMappingOverride<Club>
    {
        public void Override(AutoMapping<Club> mapping_)
        {
            mapping_
                .HasManyToMany(x_ => x_.Members)
                .ParentKeyColumn("ClubId")
                .ChildKeyColumn("MemberId")
                .Inverse()
                .Table("ClubMembers");
        }
    }

I can see from my overrides that the Inverse on the ClubOverride means you cannot do the following

    session.Save(club.Members.Add(member));

but this works:

    session.Save(member.Clubs.Add(club);

But it doesn't make logical sense. I want to be able to save either the club with members or member with clubs.

Am I trying to do something impossible with FluentNhibernate?

TIA

2012-04-04 18:05
by Alan Alcock


3

Yes, you're right, that's not possible. But it's not a question of FluentNhibernate, NHibernate works like that.

Only one side is the owner of the relation and on charge of adding elements.

From official documentation:

Changes made only to the inverse end of the association are not persisted. This means that NHibernate has two representations in memory for every bidirectional association, one link from A to B and another link from B to A. This is easier to understand if you think about the .NET object model and how we create a many-to-many relationship in C#:

2012-04-04 18:20
by Claudio Redi
clear and concise response to my question. Thanks - Alan Alcock 2012-04-13 08:36


3

You can create add or remove methods on your entities that will help accomplish this:

public class Club() {
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    private IList<Member> members;
    public virtual IEnumerable<Member> Members { get { return members.Select(x => x); } }

    public Club() {
        members = new List<Member>();
    }

    public virtual void AddMember(Member member){
        if (members.Contains(member))
            return;

        members.Add(user);
        member.AddClub(this);
    }

    public virtual void RemoveMember(Member member){
        if (!members.Contains(member))
            return;

        members.Remove(member);
        member.RemoveClub(this);
    }
}
2012-04-05 11:54
by Cole W
thanks Cole W. This is a good way to accomplish what I need to do given the behaviour of NHibernate - Alan Alcock 2012-04-13 08:38
Ads