I have struggled with the relatively simple issue:
In the parent class I map:
HasMany(x => x.States)
.KeyColumn("WorkflowOid")
.Inverse()
.Cascade.All()
.Not.LazyLoad();
The DB has the column WorkflowOid in the child table.
In the child mapping class:
References(x => x.Workflow)
.Column("WorkflowOid");
Considering a new Workflow object with a State in the "States" list, is there a way to automatically recognize that the parent is the workflow object, without having to set the "Workflow" variable in the child?
I mean, when I save a Workflow object with a State which does not have the Workflow variable set to the parent instance causes the column "WorkflowOid" in the child to be null.
Not the way you currently have it mapped. You have the parent relationship mapped as Inverse()
meaning that it is not responsible for saving the relationship on the child object.
You do have a Cascade.All()
set, but the parent is simply calling SaveOrUpdate()
on the child, the child doesn't have a parent set, so it's saving null
for the WorkflowOid from it's null Workflow
property.
Here are some ways to fix this:
1) Have a method on the parent called AddState(State state)
and when you call it, make it set state.Workflow = this
as well as adding it to the States
collection.
2) Make the parent responsible for saving the relationship with the child by removing Inverse()
, and set the child as Inverse()
instead, this means that only saving a parent could ever write to the WorflowOid column.
3) Remove Inverse()
from the parent, and don't link the child to the parent at all, this will mean that on new child creation only (but not updates) you would get both a Save()
(save the child) and Update()
(add the WorkflowOid to it) event, which is ineffecient, but sometimes having a nicer/more sensible codebase trumps this. Obviously in this case you could only get children via their parents too.