我有一个重复的可配置任务,它接收一个表名和一个列名,然后从该表中获取按指定列排序的行并对它们进行一些处理。最后,它保存 order 列的最后一个值,这样当它再次启动时,它只处理从该点开始的行。
为了保存该信息,我有一个不同的表,其中包含一些识别信息(表名等)和 order 列的最后一个值作为字符串。为了使用这张桌子,我做了类似的事情:
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 过滤,我'将再次获取它们)。
第二个是 default(DateTime) 返回日期 Jan 1st 0001,如果我尝试将该日期发送回以获取日期大于该日期的行,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)?