【问题标题】:Working with Time Type in Fluent Nhibernate generates exception "Unable to cast object of type 'System.DateTime' to type 'NHibernate.Type.TimeType"在 Fluent Nhibernate 中使用时间类型会生成异常“无法将 'System.DateTime' 类型的对象转换为类型 'NHibernate.Type.TimeType”
【发布时间】:2014-10-08 21:51:22
【问题描述】:

我发现 NHibernate 有几个内置的类型,它们在 C# 中不存在,但在某些 SGBD 中存在。

现在我有以下内容:

public class TimeSlot : EntityBase
{            
    public virtual NHibernate.Type.TimeType FromTime { get; set; }
    public virtual NHibernate.Type.TimeType ToTime { get; set; }
}

public class TimeSlotMap : ClassMap<TimeSlot>
{
    public TimeSlotMap()
    {
        Id(c => c.Id).GeneratedBy.Identity();
        Map(c => c.FromTime);
        Map(c => c.ToTime);                     
    }
}

在 MSSQL 中,此表与附件中的图片类似

现在,当我尝试查询此表时,出现以下异常:

无法将“System.DateTime”类型的对象转换为“NHibernate.Type.TimeType”类型

我做错了什么? Fluent NHibernate 如何处理时间日期类型?

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate nhibernate-mapping


    【解决方案1】:

    我建议将TimeSpan 用于DB 类型Time

    public class TimeSlot : EntityBase
    {
        public virtual TimeSpan FromTime { get; set; }
        public virtual TimeSpan ToTime { get; set; }
    }
    

    然后 NHibernate 确实有一个特殊的类型来处理这个技巧:

    Map(c => c.FromTime)
       .Type<NHibernate.Type.TimeAsTimeSpanType>();
    ...
    

    这将允许您使用 .NET 本机“类似时间”类型 -

    MSDN - TimeSpan Structure

    表示时间间隔。

    那么NHibernate.Type.TimeType 是什么?

    如果我们更喜欢使用DateTime,NHibernate 可以使用它来表示时间,我们必须这样做:

    public class TimeSlot : EntityBase
    {
        public virtual DateTime FromTime { get; set; }
        public virtual DateTime ToTime { get; set; }
    }
    

    现在我们可以使用问题中的类型 - NHibernate.Type.TimeType

    Map(c => c.FromTime)
       .Type<NHibernate.Type.TimeType>();
    ...
    

    描述是:

    /// <summary>
    /// Maps a <see cref="System.DateTime" /> Property to an DateTime column that only stores the 
    /// Hours, Minutes, and Seconds of the DateTime as significant.
    /// Also you have for <see cref="DbType.Time"/> handling, the NHibernate Type <see cref="TimeAsTimeSpanType"/>,
    /// the which maps to a <see cref="TimeSpan"/>.
    /// </summary>
    /// <remarks>
    /// <para>
    /// This defaults the Date to "1753-01-01" - that should not matter because
    /// using this Type indicates that you don't care about the Date portion of the DateTime.
    /// </para>
    /// <para>
    /// A more appropriate choice to store the duration/time is the <see cref="TimeSpanType"/>.
    /// The underlying <see cref="DbType.Time"/> tends to be handled differently by different
    /// DataProviders.
    /// </para>
    /// </remarks>
    [Serializable]
    public class TimeType : PrimitiveType, IIdentifierType, ILiteralType
    

    同时检查:

    Date/Time Support in NHibernate

    ... 与时间相关的 DbTypes 只存储时间,但不存储日期。在 .NET 中,没有 Time 类,因此 NHibernate 使用 DateTime 并将日期组件设置为 1753-01-01,SQL 日期时间或 System.TimeSpan 的最小值 - 取决于我们选择的 DbType...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-26
      • 2017-07-30
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2015-02-10
      • 2017-05-05
      • 1970-01-01
      相关资源
      最近更新 更多