在花了好几个小时浏览 NHibernate 源代码后,我终于能够确定为什么RegisterKeyword("SQL_INTEGER")
不起作用。该方法Template.RenderWhereStringTemplate
用于生成公式SQL。此方法调用ToLowerInvariant()
它处理的每个字符串标记,因此当该方法检查它查找的保留关键字列表时sql_integer
,因此找不到它。RegisterKeyword("sql_integer")
在我们的自定义方言中更改调用后,生成了正确的 SQL:
CONVERT(hostplacem0_.alloc_code, SQL_INTEGER)
为了完整起见,我还检查了是否可以通过访问方言类SessionFactoryImpl
并通过反射调用来注入新的关键字RegisterKeyword
,即
var factory_impl = factory as SessionFactoryImpl;
if (factory_impl != null)
{
MethodInfo mInfoMethod = typeof(Dialect).GetMethod(
"RegisterKeyword",
BindingFlags.Instance | BindingFlags.NonPublic,
Type.DefaultBinder,
new[] { typeof(string) },
null);
mInfoMethod.Invoke(factory_impl.Dialect, new object[] { "sql_integer" });
}
虽然这段代码工作 NHibernate 仍然发出不正确的 SQL。Dialect.GetDialect
不幸的是,每次使用该方法请求方言对象时,NHibernate 都会创建一个新的方言实例。
我想解决这个问题的唯一方法是做我们所做的。完全创建自己的方言,就像在我们的情况下一样,或者通过从现有方言中子类化并将调用添加RegisterKeyword
到构造函数中。