为何Fluent NHibernate创建表失败时未抛出异常?
问题分析与解决
为什么NHibernate没抛出建表失败的异常?
NHibernate在自动执行DDL(比如hbm2ddl.auto设为create/update)时,默认的错误处理逻辑不会把SQL Server保留字冲突这类错误直接抛到应用层。原因在于早期版本的NHibernate为了兼容多数据库,对DDL执行的异常捕获范围较宽,部分数据库驱动的错误反馈也没被正确识别,导致这类静默失败。
需要开启哪些配置来捕获这类错误?
- 开启SQL日志输出:通过
ShowSql()和FormatSql()配置,能直接在日志或控制台看到生成的DDL语句,快速定位保留字问题:Fluently.Configure() .Database(MsSqlConfiguration.MsSql2012 .ConnectionString(c => c.FromConnectionStringWithKey("YourConnString")) .ShowSql() .FormatSql()) - 强制自动转义保留字:设置
KeywordAutoImport(Hbm2DDLKeyWords.AutoQuote),让NHibernate自动给SQL保留字加方括号(比如User变成[User]),从根源避免语法错误,同时确保DDL执行成功:Fluently.Configure() .Database(MsSqlConfiguration.MsSql2012 .ConnectionString(c => c.FromConnectionStringWithKey("YourConnString")) .KeywordAutoImport(Hbm2DDLKeyWords.AutoQuote)) - 确保异常能被抛出:如果使用批量执行(
adonet.batch_size>0),可能会导致异常被吞,建议暂时设为0,或者通过日志框架(比如NLog、Serilog)捕获NHibernate的DDL执行日志,排查错误。
这算不算NHibernate的Bug?
不算严格意义上的Bug,属于设计取舍:早期NHibernate优先考虑多数据库兼容性,没有对所有DDL错误做强制抛出,依赖开发者通过日志排查。不过在NHibernate 5.x及以上版本中,对保留字的检测和错误反馈已经做了优化,这类问题的出现概率降低。
临时解决办法
如果不想改属性名,也可以在实体映射中显式给列名加方括号:
public class OptionMap : ClassMap<Option> { public OptionMap() { // 其他属性映射 Map(x => x.User).Column("[User]"); } }
内容的提问来源于stack exchange,提问作者Gener4tor
相关产品推荐
相关产品推荐

