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

时间:2011-07-19 17:12:58

标签: sql nhibernate sql-server-2008 fluent-nhibernate time

我正在使用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被抓住了   Message =无法执行查询
  [SELECT TOP(@ p0)this_.TimeTableEventId as TimeTabl1_15_1_,   this_.Day为Day15_1_,this_.StartTime为StartTime15_1_,   this_.Endtime为Endtime15_1_,this_.TimeTableId为TimeTabl5_15_1_,   this_.RequiredSettingsId为Required6_15_1_,   requiredse2_.RequiredSettingsId as Required1_10_0_,   requiredse2_.BackgroundColor as Backgrou2_10_0_,requiredse2_.Title as   Title10_0_ FROM TimeTableEvents this_ inner join RequiredSettings   requiredse2_ on   this_.RequiredSettingsId = requiredse2_.RequiredSettingsId WHERE   this_.TimeTableId in(@ p1)]
  位置参数:#0&gt; 14
  [SQL:SELECT TOP(@ p0)this_.TimeTableEventId as TimeTabl1_15_1_,   this_.Day为Day15_1_,this_.StartTime为StartTime15_1_,   this_.Endtime为Endtime15_1_,this_.TimeTableId为TimeTabl5_15_1_,   this_.RequiredSettingsId为Required6_15_1_,   requiredse2_.RequiredSettingsId as Required1_10_0_,   requiredse2_.BackgroundColor as Backgrou2_10_0_,requiredse2_.Title as   Title10_0_ FROM TimeTableEvents this_ inner join RequiredSettings   requiredse2_ on   this_.RequiredSettingsId = requiredse2_.RequiredSettingsId WHERE   this_.TimeTableId in(@ p1)]
  来源= NHibernate的
  SqlString = SELECT TOP(@ p0)this_.TimeTableEventId as   TimeTabl1_15_1_,this_ .Day as Day15_1_,this_.StartTime as   StartTime15_1_,this_.Endtime为Endtime15_1_,this_.TimeTableId为   TimeTabl5_15_1_,this_.RequiredSettingsId为Required6_15_1_,   requiredse2_.RequiredSettingsId as Required1_10_0_,   requiredse2_.BackgroundColor as Backgrou2_10_0_,requiredse2_.Title as   Title10_0_ FROM TimeTableEvents this_ inner join RequiredSettings   requiredse2_ on   this_.RequiredSettingsId = requiredse2_.RequiredSettingsId WHERE   (@ p1)

中的this_.TimeTableId      

堆栈跟踪:
  在NHibernate.Loader.Loader.DoList(ISessionImplementor   session,QueryParameters queryParameters)
  在NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor   session,QueryParameters queryParameters)
  在NHibernate.Loader.Loader.List(ISessionImplementor   session,QueryParameters queryParameters,ISet 1 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.QueryOver
1.ListU
  在NHibernate.Criterion.QueryOver`1.NHibernate.IQueryOver.ListU
  在TimeTableRepo.cs:第47行   在TimeTableService.cs:第43行   InnerException:System.FormatException
  消息=输入字符串'16:00:00'不正确   格式。
  来源= NHibernate的
  堆栈跟踪:
  在NHibernate.Type.DateTimeType.Get(IDataReader rs,   Int32指数)
  在NHibernate.Type.NullableType.NullSafeGet(IDataReader rs,String name)
  在NHibernate.Type.NullableType.NullSafeGet(IDataReader rs,String []   名称,ISessionImplementor会话,对象所有者)
  在NHibernate.Type.AbstractType.Hydrate(IDataReader   rs,String [] name,ISessionImplementor session,Object owner)
  在NHibernate.Persister.Entity.AbstractEntityPersister.Hydrate(IDataReader)   rs,Object id,Object obj,ILoadable rootLoadable,String [] []   suffixedPropertyColumns,Boolean allProperties,ISessionImplementor   会议)
  在NHibernate.Loader.Loader.LoadFromResultSet(IDataReader rs,Int32 i,   Object obj,String instanceClass,EntityKey key,String rowIdAlias,   LockMode lockMode,ILoadable rootPersister,ISessionImplementor   会议)
  在NHibernate.Loader.Loader.InstanceNotYetLoaded(IDataReader dr,Int32 i,   ILoadable persister,EntityKey键,LockMode lockMode,String   rowIdAlias,EntityKey optionalObjectKey,Object optionalObject,IList   hydratedObjects,ISessionImplementor session)
  在NHibernate.Loader.Loader.GetRow(IDataReader rs,   ILoadable [] persisters,EntityKey []键,Object optionalObject,   EntityKey optionalObjectKey,LockMode [] lockModes,IList   hydratedObjects,ISessionImplementor session)
  在NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet,   ISessionImplementor会话,QueryParameters queryParameters,   LockMode [] lockModeArray,EntityKey optionalObjectKey,IList   hydratedObjects,EntityKey [] keys,Boolean 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   session,QueryParameters queryParameters)
  InnerException:System.InvalidCastException
  Message =无法转换类型的对象   '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;
}

4 个答案:

答案 0 :(得分:3)

答案 1 :(得分:1)

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

答案 2 :(得分:1)

当您收到错误消息

时,明确地提出VahidN的答案
Unable to cast object of type 'System.TimeSpan' to type 'System.IConvertible'.

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

答案 3 :(得分:0)

我觉得有用的部分解决方案是在映射中使用formula=CONVERT(DateTime, <ColumnName>)

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