ReadXmlSchema定义的DataSet:为什么填充后列数据类型会发生变化?

时间:2013-01-04 21:00:35

标签: asp.net vb.net .net-4.0 xsd .net-2.0

我有一个将数据库调用的结果导出到CSV文件的进程。数据类型和文件格式必须与特定格式匹配,以便可以将文件上载到外部系统。这个过程在ASP.NET(.NET 2.0)webform上运行了大概7到8年,并且突然(在过去6-18个月的某个时间)它不像以前那样运行。也许在客户端服务器上安装.NET 4.0之后,或者可能在其他框架更新(?)或Windows更新(?)或提供程序更新(?)之后。我们的DLL在几年内没有改变。我想用尽可能少的黑客攻击和削减来修复这个遗留流程。

导出三种数据类型:整数,字符串和小数。 问题是所有整数列现在都以小数形式导出。 CSV导出库查看列的数据类型以确定正确的输出格式,因此我使用XSD文件来定义我的DataSet在填写之前。以下是XSD文件的简化示例:

<?xml version="1.0" standalone="yes"?>
<xs:schema id="FDSR" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="FDSR" msdata:IsDataSet="true" msdata:Locale="en-CA">
    <xs:complexType>
      <xs:choice maxOccurs="unbounded">
        <xs:element name="TBLEXPORT">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="INTCOLUMN1" type="xs:integer" minOccurs="0" />
              <xs:element name="STRCOLUMN2" type="xs:string" minOccurs="0" />
              <xs:element name="DBLCOLUMN3" type="xs:decimal" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

为每个列定义的数据类型,用于在加载数据后保留,但现在它们由数据加载重置。例如:

Dim ds as New DataSet
ds.ReadXmlSchema("MyFile.xsd")

' Breakpoint here: 
' ds.Tables(0).Columns(0).DataType shows: {Name = "Int64" FullName = "System.Int64"}

Dim db as New DatabaseCall("my db call...")    
ds = db.ReturnData()

' Breakpoint here: 
' ds.Tables(0).Columns(0).DataType now shows: {Name = "Decimal" FullName = "System.Decimal"}

GenerateCSVOutput(ds)

如何在数据库调用后强制integer列保持integer?或者如何在填充数据集后更改数据类型?

此代码已经过简化以便发布,但基本上db.ReturnData()调用Oracle存储过程进行一些处理并使用System.Data.OracleClient.OracleDataAdapter.Fill(dataset)返回数据以填充DataSet。 Oracle中没有integer列,因此源表的列定义为NUMBER(1,0)。它肯定输出正确的精度,我只是不明白为什么DataSet中的列类型在明确定义为整数时突然改变。遗憾的是,CSV文件需要上传到外部政府系统,该系统不接受1.0 1 ...

1 个答案:

答案 0 :(得分:1)

解决方法: Clone the DataSet, change the data type, copy the data

Dim dsExport as New DataSet
'dsExport.ReadXmlSchema("MyFile.xsd") ' Don't bother, this no longer works

Dim db as New DatabaseCall("my db call...")    
dsExport = db.ReturnData()

' Clone the structure of dsExport, while empty change the datatype(s) as required, then copy the data in
Dim dsClone As DataSet = dsExport.Clone
dsClone.Tables("tblExport").Columns("INTCOLUMN1").DataType = System.Type.GetType("System.Int32")
For Each row As DataRow In dsExport.Tables("tblExport").Rows
    dsClone.Tables("tblExport").ImportRow(row)
Next

GenerateCSVOutput(dsClone)