【发布时间】:2011-09-15 11:02:38
【问题描述】:
昨天,一位 DBA 提出了一个问题,我质疑我的一位同事。我们的一个对象上有一个TimeSpan 属性,它必须被持久化。是的,您可以从对象的 Start 和 End DateTime 属性推断值,但 DBA 坚持认为该值保存在数据库表中。
因此,DBA 选择保存该值的 Oracle 数据类型是 INTERVAL DAY(2) TO SECOND(6)。
Oracle.DataAccess 中的对应类型是 OracleDbType.InvervalDS,但我无法找到任何与如何使用 NHibernate 进行映射相关的内容。
我们最终得到了这个解决方案
public class SomeTimeSpanTestClass
{
public virtual string TimeSpanTest { get; protected set; }
public virtual TimeSpan ActualTimeSpan
{
get
{
// Need to do some formatting of TimeSpanTest before it can be parsed
return TimeSpan.Parse(TimeSpanTest);
}
set
{
TimeSpanTest = string.Format("{0}{1} {2}:{3}:{4}.{5}",
value.ToString().Contains('-') ? "-" : "+",
value.Days.ToString().Contains('-') ? value.Days.ToString().Substring(1).PadLeft(2, '0') : value.Days.ToString().PadLeft(2, '0'),
value.Hours.ToString().Contains('-') ? value.Hours.ToString().Substring(1).PadLeft(2, '0') : value.Hours.ToString().PadLeft(2, '0'),
value.Minutes.ToString().Contains('-') ? value.Minutes.ToString().Substring(1).PadLeft(2, '0') : value.Minutes.ToString().PadLeft(2, '0'),
value.Seconds.ToString().Contains('-') ? value.Seconds.ToString().Substring(1).PadLeft(2, '0') : value.Seconds.ToString().PadLeft(2, '0'),
value.Milliseconds.ToString().Contains('-') ? value.Milliseconds.ToString().Substring(1).PadLeft(6, '0') : value.Milliseconds.ToString().PadLeft(6, '0')
);
}
}
}
映射为
<property name="TimeSpanTest" column="TIMESPAN_TEST"/>
一个非常点头的测试
class Program
{
static void Main(string[] args)
{
SomeTimeSpanTestClass spanClass = new SomeTimeSpanTestClass();
DateTime start = DateTime.Now;
DateTime end = DateTime.Now.AddMinutes(75);
spanClass.ActualTimeSpan = end.Subtract(start);
Console.WriteLine(spanClass.TimeSpanTest);
}
}
显然,这段代码没有以任何方式重构,但对于本次测试而言,它无论如何都是微不足道的。
数据库中的值基本上必须看起来像这样“+00 01:15:03.000874”。如果值为负,则 - 符号在字符串的开头也有效。这里要注意的重要一点是:当值为负时,TimeSpan 对象的每个部分在孤立时都是负的,因此不是那么漂亮的“value.Days.ToString().Contains('-')” Format() 方法的每个部分。
我们的测试通过了,我们能够通过 NHibernate 将 TimeSpan 值保存并检索到定义为 INTERVAL DAY(2) TO SECOND(6) 的数据库列中。
如果有人以前做过更好的方法,我很想知道如何做。
抱歉没有链接 Oracle 类型,这是我的第一篇文章,所以我不允许...
【问题讨论】:
-
您也可以使用 NH-Usertype 来映射 Timespan-property。然后你不需要 TimeSpanTest 和对象中的转换代码。如果需要,我可以发布一个实现
-
请。就像我说的,这是我们第一次尝试,如果有更好的方法,我想知道怎么做。
标签: c# .net oracle nhibernate orm