我有一个周期性的可配置任务,它接收一个表名和一个列名,然后从该表中获取按指定列排序的行,并对它们进行一些处理。最后它会保存顺序列的最后一个值,这样当它再次开始时它只处理从那一点开始的行。
为了保存该信息,我有一个不同的表,其中包含一些标识信息(表名等)和订单列的最后一个值作为字符串。为了使用这张表,我做了类似的事情:
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) 返回日期 0001 年 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)?
最佳答案
我看到有两种方法可以完成您的任务:
- 在数据库查询中,您使用四舍五入到秒的日期时间。我是说 如果行的最后一条记录设置为您处理的是 01:23:42.578, 您忽略它并处理直到 01:23:42.000 的所有记录。这 意味着你把它留给下一个处理。然后你存储 01:23:42.000 作为配置中最后处理的日期时间值 信息表。下次你运行你的处理时,你把所有的 从 01:23:42.000 开始的记录,其中将包含一条记录 01:23:42.578,你应该在之前的运行中得到。
- 第二种解决方案涉及使用
Ticks
属性(property)如果DateTime
类型。
关于c# - 将基本类型(日期、数字)转换为字符串并返回以保存到 C# 中的数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13893210/