多对一公式将表名附加到 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 关键字的主要内容,如果未能解决你的问题,请参考以下文章

jpql语句

雪花中的 Javascript 函数将表名附加到当前日期

0914 表与表之间的关系补充一对一关系 记录操作 关键字 多对多 子查询

将表名的“字段”添加到来自 UNION 的 SQL 结果?

表关系(一对一 ,多对多)

多表查询