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

时间:2018-03-23 11:49:58

标签: c# oracle ado.net odp.net

我目前正在使用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);
        }
    }
}

我遇到的问题是,如此处所述[{3}},OracleDataAdapter隐式将我的Date对象转换为.net DateTime,因此将日期设置为不同的格式。

结果将被放入报告中,因此以SQL服务器输出的格式表示为String非常重要。到目前为止,我只是使用ToString()方法转换所有结果,如图所示,但这些日期在此之前转换。

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

编写一个方法来尝试解析C#中的任何日期也是不可接受的,因为SQL语句各不相同,并且每个Date对象都可以在任何列序号下,所以我必须尝试解析我想要的每个单元格完全避免。

干杯

1 个答案:

答案 0 :(得分:1)

如评论中所述,日期没有特定的格式。我的问题是我希望结果为字符串文字,无论其类型如何。主要是因为dataAdapter.Fill会通过将所有TimeStamps(甚至是TimeStampTZ)转换为DateTime对象来删除任何TimeZone相关数据。 SafeMapping是解决这个问题的潜在解决方案:

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

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

dataAdapter.ReturnProviderSpecificTypes = true;

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

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; }