将基本类型(日期,数字)转换为字符串并返回以便在C#中保存到数据库

时间:2012-12-15 14:49:56

标签: c# sql-server string datetime typeconverter

我有一个定期的可配置任务,它接收一个表名和一个列名,然后从该表中获取按指定列排序的行,并对它们进行一些处理。最后,它会保存订单列的最后一个值,这样当它再次启动时,它只会处理该点上的行。

为了保存该信息,我有一个不同的表,它有一些识别信息(表名,还有一些),订单列的最后一个值作为字符串。为了使用这个表,我做了类似的事情:

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)?

2 个答案:

答案 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)

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

  1. 在数据库查询中,您使用舍入为秒的日期时间。我的意思是 如果行的最后一条记录设置为01:23:42.578, 你忽略它并处理所有记录,直到01:23:42.000。这个 意味着您将其留待下一次处理。然后你存储 01:23:42.000作为配置中最后处理的日期时间值 信息表。下次运行处理时,您将完成所有操作 记录从01:23:42.000开始,其中包括记录 01:23:42.578,你应该在之前的比赛中被带走。
  2. 第二个解决方案将涉及使用Ticks属性 DateTime类型。