I'm working with a legacy database where FK's aren't always used.
For example I have an entity Person and an entity Country. A person has a Country which is mapped as a many-to-one in the Person mapping.
<many-to-one name="Country" class="Country" foreign-key="none" lazy="false" not-found="ignore" fetch="join" outer-join="true" column="countryid"/>
When person has null
as column value (countryid) it won't perform an extra select query (because it knows that there won't be a reference in the country table), but when a person has 0
as column value NH will perform another select to check the country tabel wether the country actually doesn't exist. But because we do a left outer join, NH should already know that it doesn't exist.
Just to clarify, if a the column has a value of 1
and it is present in the country table, it will not perform an extra select.
Is there anyway to tell NHibernate not to do the extra select query?
Thanks
No, there is no way how to do this via configuration. Nice post how to improve the not-found="ignore"
functionality:
http://nhforge.org/blogs/nhibernate/archive/2011/01/28/how-to-use-0-instead-of-null-for-foreign-keys.aspx
We can use some of NHibernate extension points like custom PocoEntityTuplizer
, but there is no simple configuration, no setting...
Some extract:
from the link above (read it to get more details). During the build process of the Person
entity will collection object[] values
contain also CountryProxy
. Let's say that missing in DB is one with Id == 0 (use your own logic there as needed). This proxy will be replaced with null
so no SELECT will be executed...
public class NullableTuplizer : PocoEntityTuplizer
{
public override void SetPropertyValues(object entity, object[] values)
{
for (int i = 0; i < values.Length; i++)
{
if (typeof (Country).IsAssignableFrom(getters[i ].ReturnType)
&& ((Country) values[i]).Id == 0) // missing id
{
values[i] = null; // here change a Proxy to null
}
}
base.SetPropertyValues(entity, values);
}
...