4

Я пытаюсь сохранить и загрузить DataTable в PowerShell. откладываю это так:Загрузка сериализованного DataTable в PowerShell - возвращает массив DataRows не DataTable

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

и загрузить его так:

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

Но тип я получаю обратно массив строк, а не DataTable! Это вызывает у меня серьезные проблемы, поскольку его необходимо передать в функцию, которая требует DataTable, и ее нельзя отнести к одному.

Любая помощь очень ценится, спасибо.

ответ

4

Это известная ловушка: 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 таким образом.

===

EDIT: Этот эффект известен как разворачивая. PowerShell имеет тенденцию разворачивать коллекции. Оператор запятой создает массив из одного элемента. PowerShell также разворачивает этот массив, но он не разворачивает свои элементы (наш DataTable).

Вот очень похожий вопрос:

Strange behavior in PowerShell function returning DataSet/DataTable

+0

Спасибо, но это все еще оставляет меня с проблемой: $ dt2 = (Import-CLIXML -Path «C: \ экспорт \ data.xml ") $ dt2.GetType(). Имя Объект [] $ dt2 | Get-Member ТипName: Deserialized.System.Data.DataTable – Chris

+0

В чем проблема? (Кстати, вы делаете что-то другое, чем я предлагал). –

+0

Если я сохранить таблицу в том, как вы говорите, а затем импортировать с: $ Dt = Импорт-CLIXML -path "C: \ экспорт \ data.xml" $ dt.GetType() выдает ошибку: «Ошибка вызова метода, потому что [Deserialized.System.Data.DataTable] не содержит метода с именем« GetType » Когда я передаю $ dt в свою функцию, для которой требуется DataTable, я получаю: Невозможно преобразовать« Систему .Collections.ArrayList "значение типа" System.Collections.ArrayList "для ввода" System .Data.DataTable ". – Chris