在Fluent中使用时间类型Nhibernate生成异常"无法将类型'System.DateTime'的对象强制转换为'NHibernate.Type.TimeType'

Nic*_*Nic 4 c# nhibernate nhibernate-mapping fluent-nhibernate

我发现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);                     
    }
}
Run Code Online (Sandbox Code Playgroud)

在MSSQL中,此表看起来像附加图像在此输入图像描述

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

无法将类型为"System.DateTime"的对象强制转换为"NHibernate.Type.TimeType"

我做错了什么?Fluent NHibernate如何使用Time Date Type?

Rad*_*ler 7

我建议,TimeSpan用于DB类型Time

public class TimeSlot : EntityBase
{
    public virtual TimeSpan FromTime { get; set; }
    public virtual TimeSpan ToTime { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

Map(c => c.FromTime)
   .Type<NHibernate.Type.TimeAsTimeSpanType>();
...
Run Code Online (Sandbox Code Playgroud)

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

MSDN - TimeSpan结构

表示时间间隔.

那么NHibernate.Type.TimeType是什么?

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

public class TimeSlot : EntityBase
{
    public virtual DateTime FromTime { get; set; }
    public virtual DateTime ToTime { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

Map(c => c.FromTime)
   .Type<NHibernate.Type.TimeType>();
...
Run Code Online (Sandbox Code Playgroud)

哪个描述是:

/// <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
Run Code Online (Sandbox Code Playgroud)

还检查:

NHibernate中的日期/时间支持

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