现在做的一个项目,应用的是NHibernate,所有的查询基本上是通过hql语句来写的,现在需要将生成的查询结果导出,这就遇到个问题,通过hql语句查询出来的结果返回的是IList,我没找到可以增加列名的方法。
以前调试hql的时候都是在sql server的事件探查器里查看它翻译后的sql,于是想它有没有直接将hql翻译成sql的方法呢,于是一路寻找,可惜没找到,但也发现了一些有用的东西,于是对原有的NHibernate类库做了一些破坏其封装性的修改,使我们似乎可以从外部快速获取hql翻译后的sql,我的修改过程如下:
public string GetSql( string hql)
... {
Configuration cfg = new Configuration();
cfg.AddAssembly("SafeManage.PersistentObject");
SessionImpl session = (SessionImpl)cfg.OpenSessionObject();
QueryTranslator[] translators = session.GetSqlQuery(hql);
string sourceSql = translators[0].GetSqlString();
return sourceSql ;
}
其实在每个QueryTranslator对象里都有一个SqlString对象存放这翻译后的sql,上面做的内容就是怎样由外部直接访问到这个sql。
我的推敲过程是这样的:
QueryTranslator对hql进行翻译,所以增加一方法直接返回翻译后的sql。
SessionImpl可以返回QueryTranslator,所以增加一方法,直接将QueryTranslator返回。
SessionFactoryImpl可以访问会话,所以增加一方法,直接返回会话对象
Configuration类中可以访问会话工厂,所以增加一方法直接返回SessionFactoryImpl中的SessionImpl对象。
这样的修改破坏了原有类库的封装意图,不太美妙, 由于我也是才开始应用NHibernate,对它还不太熟悉,在获取翻译后的hql的推敲过程中也是迷迷糊糊,希望有人能给出更好的思路。