我有一个定期的可配置任务,它接收一个表名和一个列名,然后从该表中获取按指定列排序的行,并对它们进行一些处理。最后,它会保存订单列的最后一个值,这样当它再次启动时,它只会处理该点上的行。
为了保存该信息,我有一个不同的表,它有一些识别信息(表名,还有一些),订单列的最后一个值作为字符串。为了使用这个表,我做了类似的事情:
public T GetValue<T>(ProgressRecord<T> record) {
string value = GetValueAsString(record); // this calls a sproc that fetches the value; the record fields are used as a filter
return value != null ? (T)Convert.ChangeType(value, typeof(T)) : default(T);
}
public void SetValue<T>(ProgressRecord<T> record) {
string value = Convert.ToString(record.value);
InnerSetValue(record, value); // this calls a sproc that saves the value; the record fields are used as a filter
}
其中ProgressRecord
包含标识信息,值为T
我正在使用default(T)
,因为如果还没有值,我将使用该类型的默认值作为过滤行的起始值。
这适用于数字类型,但DateTime
存在一些问题。
第一个是Convert.ToString(DateTime)
没有保留毫秒信息,我需要确保我不再处理相同的行(如果他们的时间是01:23:42.578,但是我过滤了从01:23:42.000,我会再次取他们)。
第二个是默认(DateTime)返回日期为1月1日的第一个,如果我尝试将该日期发送回日期大于该日期的获取行,MSSQL会抱怨日期超出范围,并且它需要在1753年1月1日之后。
所以我将代码更改为:
public T GetValue<T>(ProgressRecord<T> record) {
string value = GetValueAsString(record); // this calls a sproc that fetches the value; the record fields are used as a filter
if (value != null) {
T returnVal = (T)Convert.ChangeType(value, typeof(T));
if (typeof(T) == typeof(DateTime)) {
returnVal = (T)Convert.ChangeType(DateTime.ParseExact(value, "yyyy-MM-dd hh:mm:ss.fff"));
}
return returnVal;
}
T defaultVal = default(T);
if (typeof(T) == typeof(DateTime)) {
defaultVal = (T)Convert.ChangeType(SqlDateTime.MinValue.Value, typeof(T));
}
return defaultVal;
}
public void SetValue<T>(ProgressRecord<T> record) {
string value = Convert.ToString(record.value);
if (typeof(T) == typeof(DateTime)) {
value = record.value.ToString("yyyy-MM-dd hh:mm:ss.fff");
}
InnerSetValue(record, value); // this calls a sproc that inserts/updates the value; the record fields are used as a filter
}
由于IF,我觉得这段代码很脏。是否有更简单的方法来进行这些转换,而不需要进行类型检查?是否有任何我错过的系统类知道如何执行此操作:将日期转换为字符串,返回毫秒数,并为空值提供自定义默认值(SQLDateTime.MinValue)?
答案 0 :(得分:0)
标准Convert.ToString(DateTime value)
只是致电value.ToString()
DateTime.ToString()
实际上正在调用
DateTimeFormat.Format(this, null, DateTimeFormatInfo.CurrentInfo)
所以基本上如果你用特定的dtfi改变文化设置,你可以在最后设置默认格式毫秒,我想你可以绕过第一个问题。
关于第二个问题,我不知道是否可以以任何优雅的方式覆盖。您可以在将值更新到数据库之前进行检查,如果它等于DateTime.MinValue
,或者,不是那么优雅,请执行以下代码,并希望没有人发现它是您做的:
typeof(DateTime).GetField ("MinValue").SetValue (typeof(DateTime), new DateTime(1753, 1, 1));
答案 1 :(得分:0)
我看到了完成任务的两种方法:
Ticks
属性
DateTime
类型。