Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
307 views
in Technique[技术] by (71.8m points)

many to many - NHibernate force not-found ignore to not execute an extra select

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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);
    }
...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...