问题
I am in the process of updating the existing *.hbm.xml files into fluent ClassMaps and have stumbled on a mistake in our mapping files, and I don't know the default behavior for me to map this correctly.
The mapping file has:
<one-to-one name="LineItemAssembly"
class="LineItemAssembly"
cascade="all-delete-orphan" />
When using Fluent, I would expect this to map to:
HasOne<LineItemAssembly>(x => x.LineItemAssembly)
.Cascade.AllDeleteOrphan();
However, AllDeleteOrphan() is not an option off of Cascade (and correctly so). I understand that is because it isn't an option and is because it is an error in the mapping file. What would be the equivalent mapping using Fluent so that my fluent mapping has the exact same functionality as the .hbm.xml file? I would think just leaving Cascade out of the Fluent mapping would be the default behavior, but I just don't know for sure.
回答1:
You can't have an orphan in a 1:1 relationship, by definition both records must exist. Deletes will always be cascade in a 1:1. I don't know why the XML maps allowed that.
回答2:
This is now supported in NHibernate 4.1 - one to one relation ship cascade "all-delete-orphan" is now properly supported (issue NH-1262 has been fixes in 4.1). I tested that and can confirm it's working - once you set the child one-to-one property to null, it issues sql delete command for the child.
Unfortunately, fluent nhibernate does not support it, as it has been last updated in 2015. But, you can build fluent nhibernate yourself from the source code (https://github.com/jagregory/fluent-nhibernate, How to build Fluent NHibernate? ; I struggled with this a bit - you need to install ruby, rubygems, run InstallGems.bat, manually run "bundle install" (was not executing for me for some reason), and build the solution using "rake" command).
Then all you have to do is to move method AllDeleteOrphan
from CollectionCascadeExpression
class to CascadeExpression
class and build it (you can also build it using visual studio 2010+ opening FluentNHibernate.sln, but you have to run "rake" command at least once).
Custom built (by me) FluentNHibernate.dll version 2.0.3.1 with HasOne AllDeleteOrphan support can be downloaded from here
回答3:
In the end, I just needed to figure out what was wrong and fix this, regardless of the default fluent behavior. With the help of http://brunoreis.com/tech/fluent-nhibernate-hasone-how-implement-one-to-one-relationship/ I was able to solve this issue.
I needed to add .Cascade.All(). However, what I really needed was a .ForeignKey() off the HasOne relationship in my mapping for the LineItemAssembly class.
来源:https://stackoverflow.com/questions/13864384/fluent-nhibernate-one-to-one-doesnt-have-cascade-all-delete-orphan