Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
311 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 Reply

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...