在PowerShell中加载序列化的DataTable - 返回DataRows数组而不是DataTable

时间:2010-11-04 16:09:52

标签: powershell xml-serialization datatable xml-deserialization

我正在尝试在PowerShell中保存和加载DataTable。 我这样保存:

$dt | Export-CliXml -path "c:\exports\data.xml"

并加载它:

$dt = Import-CliXml -path "c:\exports\data.xml"

但我得到的类型是一行Rows而不是DataTable! 这导致了我的主要问题,因为它需要传递给需要DataTable的函数,并且它不能转换为一个。

非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:5)

这是一个已知的陷阱:PowerShell将DataTable作为DataRow项的集合进行处理。这是第一个命令

$dt | Export-CliXml -path "c:\exports\data.xml"

已经“忘记”了数据表。您可以查看输出文件,它以DataRow

开头
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.Data.DataRow</T>

要避免这种影响,请使用,运算符(看起来很有趣,但这正是它的工作方式):

, $dt | Export-CliXml -path "c:\exports\data.xml"

因此,输出文件现在以DataTable

开头
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.Data.DataTable</T>

之后你可以将表格导回:

$dt = Import-CliXml -path "c:\exports\data.xml"

我们来检查一下:

$dt | Get-Member
# output:
TypeName: Deserialized.System.Data.DataRow
…

我们可以看到相同的效果(DataRow而不是DataTable)。因此,正确的命令是,

, $dt | Get-Member
# output:
TypeName: Deserialized.System.Data.DataTable
…

所以,我们真的以这种方式使DataTable脱水。

===

编辑:此效果称为展开。 PowerShell倾向于展开集合。逗号运算符创建单个项的数组。 PowerShell也会展开此数组,但它不会展开其项目(我们的DataTable)。

这是一个非常相似的问题:

Strange behavior in PowerShell function returning DataSet/DataTable