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