如何使用 NHibernate 处理来自 SQL Server 2008 的 TIME 数据类型?

Posted

技术标签:

【中文标题】如何使用 NHibernate 处理来自 SQL Server 2008 的 TIME 数据类型?【英文标题】:How to deal with TIME datatype from SQL Server 2008 with NHibernate? 【发布时间】:2011-10-08 17:37:31 【问题描述】:

我正在使用 SQL Server 2008 中的 TIME 数据类型,但在使其与 NHibernate 一起使用时遇到了一些问题。

public TimeTableEventMap()

    Id(x => x.Id)
    Map(x => x.Day).NvarcharWithMaxSize().Not.Nullable();
    Map(x => x.StartTime).Length(4).TimeDataType().Not.Nullable();
    Map(x => x.Endtime).Length(4).TimeDataType().Not.Nullable();
    References(x => x.TimeTable).Not.Nullable().Cascade.All();
    References(x => x.RequiredSettings).Not.Nullable().Cascade.All();


/// <summary>
///  MS Sql 2008 date type.
/// </summary>
/// <param name="map"></param>
/// <returns></returns>
public static PropertyPart TimeDataType(this PropertyPart map)

   return map.CustomSqlType("time");


public class TimeTableEvent

    public virtual int Id  get; private set; 
    public virtual DayOfWeek Day  get; set; 
    public virtual DateTime StartTime  get; set; 
    public virtual DateTime Endtime  get; set; 
    public virtual TimeTable TimeTable  get; set; 
    public virtual RequiredSetting RequiredSettings  get; set; 
   

我收到此错误

NHibernate.Exceptions.GenericADOException 被捕获 消息=无法执行查询 [ SELECT TOP (@p0) this_.TimeTableEventId 作为 TimeTable1_15_1_, this_.Day 作为 Day15_1_,this_.StartTime 作为 StartTime15_1_, this_.Endtime 作为 Endtime15_1_,this_.TimeTableId 作为 TimeTable5_15_1_, this_.RequiredSettingsId 为Required6_15_1_, requiredse2_.RequiredSettingsId 为Required1_10_0_, requiredse2_.BackgroundColor 作为 Backgrou2_10_0_,requiredse2_.Title 作为 Title10_0_FROM TimeTableEvents this_inner join RequiredSettings 需要se2_ on this_.RequiredSettingsId=requiredse2_.RequiredSettingsId WHERE this_.TimeTableId in (@p1) ] 位置参数:#0>14 [SQL: SELECT TOP (@p0) this_.TimeTableEventId 作为 TimeTable1_15_1_, this_.Day 作为 Day15_1_,this_.StartTime 作为 StartTime15_1_, this_.Endtime 作为 Endtime15_1_,this_.TimeTableId 作为 TimeTable5_15_1_, this_.RequiredSettingsId 为Required6_15_1_, requiredse2_.RequiredSettingsId 为Required1_10_0_, requiredse2_.BackgroundColor 作为 Backgrou2_10_0_,requiredse2_.Title 作为 Title10_0_FROM TimeTableEvents this_inner join RequiredSettings 需要se2_ on this_.RequiredSettingsId=requiredse2_.RequiredSettingsId WHERE this_.TimeTableId in (@p1)] 来源=NHibernate SqlString=SELECT TOP (@p0) this_.TimeTableEventId as TimeTabl1_15_1_, this_.Day 为 Day15_1_, this_.StartTime 为 StartTime15_1_, this_.Endtime as Endtime15_1_, this_.TimeTableId as TimeTabl5_15_1_, this_.RequiredSettingsId 为Required6_15_1_, requiredse2_.RequiredSettingsId 为Required1_10_0_, requiredse2_.BackgroundColor 作为 Backgrou2_10_0_,requiredse2_.Title 作为 Title10_0_FROM TimeTableEvents this_inner join RequiredSettings 需要se2_ on this_.RequiredSettingsId=requiredse2_.RequiredSettingsId WHERE this_.TimeTableId in (@p1)

堆栈跟踪: 在 NHibernate.Loader.Loader.DoList(ISessionImplementor 会话,QueryParameters queryParameters) 在 NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor 会话,QueryParameters queryParameters) 在 NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet1 querySpaces, IType[] resultTypes) at NHibernate.Loader.Criteria.CriteriaLoader.List(ISessionImplementor session) at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) at NHibernate.Impl.CriteriaImpl.List(IList results) at NHibernate.Impl.CriteriaImpl.List[T]() at NHibernate.Criterion.QueryOver1.ListU 在 NHibernate.Criterion.QueryOver`1.NHibernate.IQueryOver.ListU 在 TimeTableRepo.cs:第 47 行 在 TimeTableService.cs:第 43 行 内部异常:System.FormatException 消息=输入字符串 '16:00:00' 不正确 格式。 来源=NHibernate 堆栈跟踪: 在 NHibernate.Type.DateTimeType.Get(IDataReader rs, Int32 索引) 在 NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, 字符串名称) 在 NHibernate.Type.NullableType.NullSafeGet(IDataReader rs,字符串 [] 名称、ISessionImplementor 会话、对象所有者) 在 NHibernate.Type.AbstractType.Hydrate(IDataReader rs、String[] 名称、ISessionImplementor 会话、对象所有者) 在 NHibernate.Persister.Entity.AbstractEntityPersister.Hydrate(IDataReader rs, 对象 id, 对象 obj, ILoadable rootLoadable, String[][] suffixedPropertyColumns, Boolean allProperties, ISessionImplementor 会话) 在 NHibernate.Loader.Loader.LoadFromResultSet(IDataReader rs, Int32 i, 对象 obj、String instanceClass、EntityKey 键、String rowIdAlias、 LockMode lockMode, ILoadable rootPersister, ISessionImplementor 会话) 在 NHibernate.Loader.Loader.InstanceNotYetLoaded(IDataReader 博士,Int32 我, ILoadable 持久化器、EntityKey 键、LockMode lockMode、String rowIdAlias、EntityKey optionalObjectKey、Object optionalObject、IList hydradObjects, ISessionImplementor 会话) 在 NHibernate.Loader.Loader.GetRow(IDataReader rs, ILoadable[] 持久化器,EntityKey[] 键,Object optionalObject, EntityKey optionalObjectKey, LockMode[] lockModes, IList hydradObjects, ISessionImplementor 会话) 在 NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader 结果集, ISessionImplementor 会话,QueryParameters 查询参数, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydradObjects、EntityKey[] 键、布尔 returnProxies) 在 NHibernate.Loader.Loader.DoQuery(ISessionImplementor 会话, QueryParameters queryParameters, Boolean returnProxies) 在 NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) 在 NHibernate.Loader.Loader.DoList(ISessionImplementor 会话,QueryParameters queryParameters) 内部异常:System.InvalidCastException 消息=无法转换类型的对象 'System.TimeSpan' 输入 'System.IConvertible'。 来源=mscorlib

public List<TimeTableEvent> GetTimeTableEvents(Student student, List<int> timeTableIds)

    TimeTableEvent tAlias = null;

    List<TimeTableEvent> allEvents = session.QueryOver<TimeTableEvent>(() => tAlias)
        .Where(Restrictions.In(Projections.Property(() => tAlias.TimeTable.Id), timeTableIds))
        .Fetch(r => r.RequiredSettings).Eager
        .TransformUsing(Transformers.DistinctRootEntity)
        .Take(QueryLimits.TimeTableEvents)
        .List<TimeTableEvent>().ToList();

    return allEvents;

【问题讨论】:

TIME 数据类型有一个参数 - 它是如何定义的? @JNK - 我在我的 ms sql 2008 数据库中有一个 4 so time(4)。 第一次谷歌搜索 ***.com/q/5301607/40822 看起来你需要在 .net 端使用 System.TimeSpan。 【参考方案1】:

Date/Time Support in NHibernate

【讨论】:

漂亮!这正是我正在寻找的信息。【参考方案2】:

您应该在 .NET 方面使用 TimeSpan 类型,而不是像 Dotjoe 在他的评论中所说的 DateTime(因为没有日期)。

【讨论】:

从这张图表看来,jameskovacs.com/2011/01/26/datetime-support-in-nhibernate 似乎 datetime 应该可以工作。我不记得我是否尝试过时间跨度(我想我会的)。无论如何,我目前不在那个项目上工作。所以我还需要一段时间才能测试它。【参考方案3】:

当您收到一条错误消息时,明确提出 VahidN 的答案

Unable to cast object of type 'System.TimeSpan' to type 'System.IConvertible'.

这意味着您尝试映射到的属性应该是 TimeSpan 而不是 DateTime。与 DateTimeOffset 相同。

【讨论】:

【参考方案4】:

我发现有用的部分解决方案是在映射中使用formula=CONVERT(DateTime, &lt;ColumnName&gt;)

显着的缺点是这只对只读访问有用。

【讨论】:

以上是关于如何使用 NHibernate 处理来自 SQL Server 2008 的 TIME 数据类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 NHibernate 中使用 sql 查询创建表?

NHibernate.Spatial 和 Sql 2008 地理类型 - 如何配置

如何使用 DISTINCT 在 NHibernate SQL 查询中进行分页

如何在nHibernate中使用datediff sql函数?

如何使用 SQL Server 2005 在 NHibernate 中映射 uint

如何使用 NHibernate QueryOver 重新创建这个复杂的 SQL 查询?