I'm using Fluent NHibernate and I'm trying to map a many-to-many property that simply bypasses the join table. The tricky thing is, the join table has a column that determines what type of relationship it is.
For the purpose of this question, let's say I have a person table and a relation table.
PersonTable (PersonId, Name, etc)
RelationTable (RelationType, PersonIdA, PersonIdB)
I want to introduce a collection property in Person class for each type of relationship e.g. Sons, Daughters, etc.
HasManyToMany<Person>(x => x.Sons)
.Table("RelationTable")
.ParentKeyColumn("PersonIdA")
.ChildKeyColumn("PersonIdB")
.Where("RelationType='A_IS_FATHER_OF_B_BOY'");
HasManyToMany<Person>(x => x.Daughters)
.Table("RelationTable")
.ParentKeyColumn("PersonIdA")
.ChildKeyColumn("PersonIdB")
.Where("RelationType='A_IS_FATHER_OF_B_GIRL'");
The above mappings are working for reading from the database but not for inserting, for example:
Person john = PersonDAO.GetByName("John"); // the Sons and Daughters are loaded fine based on mappings above
john.Sons.Add(new Person("Jack")); // let's add a new son
PersonDAO.Save(john); // this fails because RelationType is null
Basically when saving Jack as John's new son in the RelationTable I need to have RelationType populated with "A_IS_FATHER_OF_B_BOY", which is not currently happening. The directive .Where("RelationType='A_IS_FATHER_OF_B_BOY'") is only effective for loading but not for saving.
Any ideas? I think this is somewhat similar to the Discriminator attribute for subclasses.
Any help appreciated. Thanks.
I would say, exactly as you pointed out in your comment:
So the pairing object in my eyes would be
There MUST be key for this table. Just inject some IDENTITY column with SQL Server.. but have some with surrogated (business domain independent) key.
Here is our Person entity
The mapping for Sons (Daughters would be same):
That would work, if we will always assure, that when adding Son, we also properly set RelationType
This must be either part of the Businese layer AddSon() or it could be POCO public method...
NOTE: we can also map reverse end of that relation ... even without relationType filtering: