テーブル名と列名を受け取り、指定された列でソートされたそのテーブルから行をフェッチし、それらに対して何らかの処理を行う、繰り返し構成可能なタスクがあります。最後に、注文列の最後の値を保存して、再開したときにその時点以降の行のみを処理するようにします。
その情報を保存するために、いくつかの識別情報(テーブル名など)と注文列の最後の値を文字列として含む別のテーブルがあります。このテーブルを操作するために、私は次のようなことをしました。
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
。
1つ目はConvert.ToString(DateTime)
、ミリ秒の情報を保持しないことです。同じ行を再度処理しないようにするために必要です(01:23:42.578の場合、01:23:42.000からフィルタリングします。それらを再度フェッチします)。
2つ目は、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のせいで、このコードはちょっと汚いです。タイプチェックに頼らずに、これらの変換を行うためのより簡単な方法はありますか?これを行う方法を知っている、見逃したシステムクラスはありますか?日付をミリ秒単位の文字列に変換し、nullのカスタムデフォルト(SQLDateTime.MinValue)を提供しますか?