C# NHibernate查询Db2的Time类型列无映射时抛出异常如何解决
无映射配置下NHibernate原生SQL查询Db2 Time类型转换失败解决方案
核心原因:Db2的数据读取器返回Time类型字段时直接输出TimeSpan对象,而NHibernate默认的TimeSpanType处理逻辑会先尝试将字段值转为Int64再计算时间差,因此触发类型转换异常。以下3种方案都无需修改实体映射配置,可按需选择:
方案1:原生查询显式指定标量类型(推荐临时查询场景)
仅需对当前查询的Time类型字段显式指定TimeAsTimeSpan类型处理规则,不需要修改全局配置,零侵入性。
string sqlText = "Select id, name, your_time_column from myTable"; ISQLQuery query = Session.CreateSQLQuery(sqlText); // 所有Time类型字段都单独指定类型即可,其他类型字段无需额外配置 query.AddScalar("your_time_column", NHibernateUtil.TimeAsTimeSpan); // 如需强类型返回可以配合别名转实体转换器使用,不需要映射配置 // query.SetResultTransformer(Transformers.AliasToBean<MyDto>()); var result = query.List();
方案2:SQL层面转字符串后自行解析
如果不想修改NHibernate相关调用逻辑,可以直接在SQL中把Time类型转为字符串,业务代码自行解析为TimeSpan,适合列数少的一次性查询场景。
// Db2中使用CHAR函数将Time列转为标准格式的时间字符串 string sqlText = "Select id, name, CHAR(your_time_column) as time_str from myTable"; ISQLQuery query = Session.CreateSQLQuery(sqlText); var result = query.List<object[]>(); // 业务逻辑中自行完成类型转换 foreach(var row in result) { TimeSpan timeVal = TimeSpan.Parse(row[2].ToString()); // 后续业务处理 }
方案3:全局配置默认Time类型映射(推荐多查询场景)
如果项目中大量存在查询Db2 Time类型的场景,可以在NHibernate初始化时全局修改默认的TimeSpan处理规则,后续所有查询都不需要单独适配,不需要修改实体映射。
// 初始化NHibernate配置时新增如下配置即可,原有其他配置保持不变 var cfg = new Configuration(); // 原有连接字符串、驱动等配置不变 cfg.SetProperty(NHibernate.Cfg.Environment.QueryDefaultTimeSpanType, "TimeAsTimeSpan"); // 构建会话工厂 var sessionFactory = cfg.BuildSessionFactory();
内容的提问来源于stack exchange,提问作者FraROl
相关产品推荐
相关产品推荐

