我目前正在使用 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数据类型映射中所述,OracleDataAdapter将我的Date对象隐式转换为.net DateTime,从而将日期置于不同的格式。
结果被放入报表中,因此重要的是以 SQL 服务器输出的格式将其表示为字符串。到目前为止,我只是使用 ToString() 方法转换所有结果,如图所示,但这些日期在此之前被转换。
当前的解决方案是在脚本级别使用TO_CHAR,但这并不理想,我宁愿不必更改SQL。
编写一种方法来尝试解析 C# 中的任何日期也是不可接受的,因为 SQL 语句会有所不同,并且每个 Date 对象都可以在任何列序号下,因此我必须尝试解析我想完全避免的每个单元格。
干杯
如注释中所述,日期没有特定的格式。我的问题是我希望结果作为字符串文字,无论它们的类型如何。主要是因为dataAdapter.Fill会通过将所有TimeStamps(甚至TimeStampTZ)转换为DateTime对象来删除任何与时区相关的数据。SafeMapping是解决此问题的潜在解决方案:
adapter.SafeMapping.Add("*", typeof(string));
但是,这似乎在某个时候被弃用了,现在在使用时会引发异常。我的最终解决方案是使用
dataAdapter.ReturnProviderSpecificTypes = true;
这允许我将日期类型作为其各自的提供程序特定类型进行处理,因此我可以在将任何 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;
}