2

我有一个重复的可配置任务,它接收一个表名和一个列名,然后从该表中获取按指定列排序的行并对它们进行一些处理。最后,它保存 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)?

4

2 回答 2

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));
于 2012-12-15T15:46:51.660 回答
0

我看到了两种完成任务的方法:

  1. 在数据库查询中,您使用四舍五入到秒的日期时间。我的意思是,如果为您设置处理的行的最后一条记录为 01:23:42.578,则您忽略它并处理直到 01:23:42.000 的所有记录。这意味着您将其留给下一个处理。然后将 01:23:42.000 作为最后处理的日期时间值存储在配置信息表中。下次运行处理时,您将获取从 01:23:42.000 开始的所有记录,其中将包括 01:23:42.578 的记录,您应该在上一次运行时获取该记录。
  2. 第二种解决方案将涉及使用类型Ticks的属性 DateTime
于 2012-12-15T15:54:21.967 回答