您的位置:首页 > 数据库

关于 NHibernate 中 HQL 生成的 SQL

2007-05-12 08:07 239 查看
5/9 调试了一下午的程序,因为 NHibernate 根据 HQL 生成的 SQL 有问题。

HQL:SELECT t FROM CUser as t

SQL:select cuser0_.GuidUser as GuidUser, cuser0_.UserID as UserID, cuser0_.UserName as UserName, cuser0_.Password as Password from CUser cuser0_

请注意 SQL 字段别名(Alias)中的 Password,在 Access 数据库中该字段与关键字冲突(其他数据库估计也冲突),使用 ADO.NET 执行将发生以下的错误:

The SELECT statement includes a reserved word or an argument name that is misspelled or missing, or the punctuation is incorrect.

我对 NHibernate 实在不熟,最初只看错误信息,实在不明白为什么会发生错误。后来配置了 log4net,在 log4net 的帮助下,找到这个错误。前后用了 1 个多小时,好累!

可是,找导致这个错误的原因,用了 3 个小时,我一下午的时光就这么浪费了,哎。同事说,至少你对 NHibernate 熟悉了一些,呵呵。

最后在 NHibernate/Mapping/Column.cs 文件中,找到了 Alias 方法(114 行)。

将长度判断的代码注释后,保证生成的 SQL 语句全部使用了特定的别名,只是,项目不允许修改 NHibernate 的代码。没办法的。

修改后生成的 SQL 语句:

select cuser0_.GuidUser as GuidUser1_, cuser0_.UserID as UserID3_, cuser0_.UserName as UserName4_, cuser0_.Password as Password2_ from CUser cuser0_

下面是 NHibernate 1.0.4 中的该方法:

public string Alias( Dialect.Dialect d )
9public string GetAlias(Dialect.Dialect dialect)
7 string alias = name;
9 string unique = uniqueInteger.ToString() + '_';
10 int lastLetter = StringHelper.LastIndexOfLetter(name);
11 if( lastLetter == -1 )
12 alias = "column";
14 }
15 else if( lastLetter < name.Length-1 )
16 alias = name.Substring(0, lastLetter+1);
18 }
19 if ( alias.Length > dialect.MaxAliasLength )
20 alias = alias.Substring( 0, dialect.MaxAliasLength - unique.Length );
22 }
23 bool useRawName = name.Equals(alias) &&
24 !quoted &&
25 !StringHelper.EqualsCaseInsensitive(name, "rowid");
26
27 if ( useRawName )
28 return alias;
30 }
31 else
32 return alias + unique;
34 }
35}
我的疑问是:
1、是否可以通过修改配置文件,控制生成的 SQL 语句?增加限定符(Quote)、设置别名后缀等等?2、针对特定数据库的 Dialect 为什么在代码中写?而不通过配置文件的形式解决,还是我没有找到?3、为什么要判断列名长度小于 11。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: