Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self referencing many to many relationships in Fluent NHibernate automapping automapping to 1:n and not n:n

The title pretty much explains it all, I have a Member object that references 'Friends' who are also type Member.

public class Member : Entity
    {
        public Member()
        {            
            Friends = new List<Member>();
        }

        public virtual IList<Member> Friends
        {
            get; set;
        }
     }

The schema generation tool makes it a 1:n relationship while it should be a n:n relationship i.e. a column is added to the member table called member_id and no connecting table is created.

Is there any way to make a Self referencing many to many relationships in Fluent NHibernate?

I tried using an override that I got as an answer before:

public class MemberOverride : IAutoMappingOverride<Member>
{
    public void Override(AutoMapping<Member> mapping)
    {
        mapping.HasManyToMany(m => m.Friends)
               .Table("MemberFriendsLinkTable");
    }
}

but I get the error message:

"NHibernate.MappingException: Repeated column in mapping for collection: Proj.BO.Member.Friends column: Member_id"

Thanks

EDIT: I found the answer, it's to put:

mapping.HasManyToMany(m => m.Friends).ParentKeyColumn("Member_Id").ChildKeyColumn("Friend_Id")
                   .Table("MemberFriendsLinkTable").Inverse().Cascade.SaveUpdate();
like image 275
Eitan Avatar asked Mar 14 '11 07:03

Eitan


1 Answers

So that I don't have to see this question at the top of the "Unanswered NHibernate Questions" list anymore...

Eitan, the asker, discovered the solution to his own problem. He needed to specify the ParentKeyColumn and ChildKeyColumn like so:

EDIT: I found the answer, it's to put:

mapping.HasManyToMany(m => m.Friends)
    .ParentKeyColumn("Member_Id")
    .ChildKeyColumn("Friend_Id")
    .Table("MemberFriendsLinkTable")
    .Inverse()
    .Cascade.SaveUpdate();

FluentNHibernate by default names foreign key columns like so: {className}_Id. Since both ends of the many-to-many were of the same type, it wanted to use the same column name, Member_Id for both columns. Explicitly naming the columns circumvents this problem.

like image 88
Daniel Schilling Avatar answered Oct 05 '22 09:10

Daniel Schilling