使用 dataAdapter.Fill() 将 Oracle Date 类型隐式转换为 String

Implicitly convert Oracle Date type to String using dataAdapter.Fill()

我目前正在使用 ODP.net 执行大量 SQL,我正在使用 OracleDataAdapter 和 .Fill() 方法以统一的方式检索数据,如图所示:

using (var oracleCommand = new OracleCommand(query, Connection))
{
    DataSet dataSet = new DataSet();
    OracleDataAdapter dataAdapter = new OracleDataAdapter(oracleCommand);

    dataAdapter.Fill(dataSet);

    var result = new List<T>();

    foreach (DataTable table in dataSet.Tables)
    {
        foreach (DataRow row in rows)
        {
            var data = new T();
            foreach (DataColumn column in columns)
            {
                data[column.Ordinal] = row[column].ToString();
            }
            result.Add(data);
        }
    }
}

我遇到的问题是,如此处 SQL Server Data Type Mappings 所述,OracleDataAdapter 正在隐式地将我的 Date 对象转换为 .net DateTime,从而使日期采用不同的格式。

结果被放入报告中,因此重要的是将其表示为从 SQL 服务器输出的格式的字符串。到目前为止,我只是简单地使用 ToString() 方法转换所有结果,但这些日期在此之前转换。

目前的解决方案是在脚本级别使用 TO_CHAR,但这并不理想,我宁愿不必更改 SQL。

由于 SQL 语句各不相同,并且每个 Date 对象都可能在任何列序数下,因此在 C# 中编写尝试和解析任何日期的方法也是不可接受的,因此我将不得不尝试并解析我想完全避免的每一个单元格。

干杯

如评论中所述,日期没有特定格式。我的问题是我希望结果作为字符串文字,而不管它们的类型。主要是因为 dataAdapter.Fill 会通过将所有时间戳(甚至 TimeStampTZ)转换为 DateTime 对象来删除任何与时区相关的数据。 SafeMapping 是解决此问题的潜在解决方案:

adapter.SafeMapping.Add("*", typeof(string));

然而,这在某些时候似乎已被弃用,现在使用时会抛出异常。我最终的解决方案是使用

dataAdapter.ReturnProviderSpecificTypes = true;

这使我能够将 Date 类型作为它们各自的提供者特定类型来处理,因此我可以在任何 OracleTimeStampTZ 对象隐式转换为 DateTime 对象之前拦截它们,如图所示:

public static string ConvertFormat(OracleTimeStampTZ ts) { var TIME_ZONE = ((ts.GetTimeZoneOffset() < TimeSpan.Zero) ? "-" : "") + ts.GetTimeZoneOffset().ToString(@"hh\:mm"); return ts.Value.ToString(NLS_TIMESTAMP_TZ_FORMAT) + TIME_ZONE; }