多对一公式将表名附加到 SQL 关键字
Posted
技术标签:
【中文标题】多对一公式将表名附加到 SQL 关键字【英文标题】:many-to-one formula has table name appended to SQL keyword 【发布时间】:2013-03-18 15:08:55 【问题描述】:我正在使用旧数据库并尝试将 char 转换为 int 以进行多对一映射。我知道这不是一个好主意,但我坚持使用模式。
我尝试使用以下映射来执行此操作,但发现 NHibernate 正在将表名别名添加到关键字 SQL_INTEGER
。
<many-to-one name="host" formula="CONVERT(alloc_code, SQL_INTEGER)" />
生成 SQL
CONVERT(hostplacem0_.alloc_code, hostplacem0_.SQL_INTEGER)
我找到了this 的帖子,但该解决方案不适用于我的情况。
需要注意的是,我们已经为我们使用的 DBMS(Sybase Advantage 数据库服务器)推出了自己的方言,因为 NHibernate 不支持开箱即用。因此,我可以选择修改它来解决这个问题。我已经尝试将SQL_INTEGER
注册为关键字,但没有帮助。
【问题讨论】:
随机的想法,但你可以尝试在同一个方言文件中注册函数,例如见github.com/nhibernate/nhibernate-core/blob/master/src/…。 str 声明似乎很有趣 感谢@jbl 的建议。事实证明这是区分大小写的问题。请在下面查看我的答案。 感谢后续 【参考方案1】:花了好几个小时浏览 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
的调用添加到构造函数中。
【讨论】:
以上是关于多对一公式将表名附加到 SQL 关键字的主要内容,如果未能解决你的问题,请参考以下文章