如何使用 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, 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 行 内部异常: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, <ColumnName>)
。
显着的缺点是这只对只读访问有用。
【讨论】:
以上是关于如何使用 NHibernate 处理来自 SQL Server 2008 的 TIME 数据类型?的主要内容,如果未能解决你的问题,请参考以下文章
NHibernate.Spatial 和 Sql 2008 地理类型 - 如何配置
如何使用 DISTINCT 在 NHibernate SQL 查询中进行分页
如何在nHibernate中使用datediff sql函数?