NHibernate 从数据库获取时出现时间转换问题

本文关键字:时间 转换 问题 数据库 获取 NHibernate | 更新日期: 2023-09-27 18:35:09

我遇到了时间转换问题。在我的一个表中,我使用以下类存储时间数据:


public class HistoryData
{
    public virtual int HD_ID { get; set; }
    public virtual DateTime HD_DATE { get; set; }
    public virtual DateTime HD_TIME { get; set; } /* this is my time data */
    public virtual EquipmentSensor HD_EQUIPMENT { get; set; }
    public virtual float HD_VALUE { get; set; }
    public virtual HistoryDataType HD_TYPE { get; set; }
}

这是我的方法:

public List<HistoryData> getMeasures()
{
      var query = " my sql query ";
      var result = (List<HistoryData>)this.session.CreateSQLQuery(query)
                        .List<HistoryData>();
      return result;
 }

下面是 SQL 表定义:

CREATE TABLE HISTORY_DATA
(
    HD_ID               INT             NOT NULL    IDENTITY,
    HD_DATE             DATE            NOT NULL            ,
    HD_TIME             TIME(0)         NOT NULL            ,
    HD_EQU_ID           INT             NOT NULL            ,
    HD_VALUE            DECIMAL(18,1)   NULL                ,
    HD_TYPE_ID          INT             NOT NULL            
)

下面是堆栈跟踪:

{"Input string '00:01:01' was not in the correct format."}
{"Unable to cast object of type 'System.TimeSpan' to type 'System.IConvertible'."}
could not execute query 

这是我的映射文件:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping
xmlns="urn:nhibernate-mapping-2.2"
assembly="DaFyDaC"
namespace="DaFyDaC.Models.KPIs"
auto-import="true">
  <class name="DaFyDaC.Models.KPIs.HistoryData, DaFyDaC" table="HISTORY_DATA">
    <id name="HD_ID" access="property" type="int">
      <generator class="native"/>
    </id>
    <property name="HD_DATE" type="Date"/>
    <property name="HD_TIME" type="Time"/>
    <property name="HD_VALUE" type="float"/>
    <many-to-one class="DaFyDaC.Models.Configuration.EquipmentSensor" name="HD_EQUIPMENT" column="HD_EQU_ID" not-found="ignore"/>
    <many-to-one class="HistoryDataType" name="HD_TYPE" column="HDT_ID" not-found="ignore"/>
  </class>
</hibernate-mapping>

你能帮我修复它吗?

NHibernate 从数据库获取时出现时间转换问题

HD_TIME列将转换为 System.TimeSpan,将TD_TIME的数据类型设为 TimeSpan:

public virtual TimeSpan HD_TIME { get; set; } 

C# 属性定义应为类型TimeSpan

public virtual TimeSpan HD_TIME { get; set; } 

xml 映射应如下所示:

<property name="HD_TIME" type="Time" 
          type="NHibernate.Type.TimeAsTimeSpanType" />

为什么会这样?因为默认情况下TimeSpan表示(对于 NHibernate)为 DbType.Int64 。但是TimeAsTimeSpanType将允许我们将其与 DB 类型等时间一起使用......

另请参见 5.2.2。基本值类型

查询

有了这个映射,我们甚至可以查询这样的列。 例如,要查找在 12:00 到 18:00 之间跟踪的所有记录,我们可以使用这样的查询:

var lowerBound = new TimeSpan(0, 12, 0, 0);
var upperBound = new TimeSpan(0, 18, 0, 0);
var query = session.QueryOver<HistoryData>()
    .WhereRestrictionOn(c => c.HD_TIME)
        .IsBetween(lowerBound)
        .And(upperBound)
    ...
    .Take(10) // paging
    .Skip(10)
    ;
var result = query.List<HistoryData>();

这里非常重要的注意事项是,NHibernate工厂配置不能(通常通常)

<property
    name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>

但必须Sql2008ClientDriver

<property 
    name="connection.driver_class">NHibernate.Driver.Sql2008ClientDriver</property>

(即使对于 SQL Server 2012+)

用于时间数据的正确类型是 TimeSpan。所有 ADO.Net 提供程序都将时间类型(如果可用)映射到此类型,而不是 DateTime。像 NHibernate 和 Entity Framework 这样的 ORM 遵循 ADO.Net 约定,除非被提供程序重写,因此时间类型映射到 TimeSpan。

改变

public virtual DateTime HD_TIME { get; set; }

public virtual TimeSpan HD_TIME { get; set; }

此外,请确保更新映射以反映新类型。