从数据库中获取时的NHibernate时间转换问题

时间:2014-12-23 13:04:47

标签: c# nhibernate

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


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>

你能帮我解决一下吗?

3 个答案:

答案 0 :(得分:1)

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

public virtual TimeSpan HD_TIME { get; set; } 

答案 1 :(得分:1)

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 将允许我们将其与时间类似的数据库类型...

另见5.2.2. Basic value types

<强>查询

有了这个映射,我们甚至可以查询这样的列。例如。要查找在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 Factory配置不能(通常是常用的)

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

但必须 Sql2008ClientDriver

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

(即使对于SQL Server 2012 +)

答案 2 :(得分:0)

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

更改

public virtual DateTime HD_TIME { get; set; }

public virtual TimeSpan HD_TIME { get; set; }

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