关于 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。
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。
相关文章推荐
- 关于Nhibernate中的hql与sql的转换问题
- [NHibernate]利用LINQPad查看NHibernate生成SQL语句
- 关于SQL和HQL时间类型的模糊查询
- 关于sql脚本导入Oracle时重复生成check约束的问题解决
- 《关于SQL语句的自动生成!》一文的代码调用示例
- 关于SQL生成随机字符串
- Hibernate中关于多表连接查询hql 和 sql 返回值集合中对象问题
- 通过Hql、Sql生成Hibernate CountQuery 字符串
- 关于T-SQL重编译那点事,内联函数和表值函数在编译生成执行计划的区别
- 关于iBatis动态sql的生成
- Mybatis:关于动态生成sql语句的一些问题
- NHibernate 查看生成的sql语句
- SET STATISTICS IO 显示关于 Transact-SQL 语句生成的磁盘活动量的信息
- Nhibernate 数据操作封装类 可以执行hql 原生sql 返回DataSet
- 两条关于生成排名的SQL语句
- 关于NHibernate下Access的使用以及NHibernate下SQL到Access的迁移
- NHibernate 查看生成的sql语句的方法
- 关于Hibernate、NHibernate的 HQL 连接字段,字段拼接查询问题
- 关于 Hibernate 的 SQLFunctionTemplate 的问题(HQL 不支持mysql 函数convert的问题)
- NHibernate——通过hql语句获取翻译后的sql语句