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
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#:
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);
}
}