Почему Powershell думает, что я пытаюсь вернуть объект [], а не DataTable?
у меня есть следующая функция PS:
function GetBuildData {
[System.Data.SqlClient.SqlConnection] $conn = New-Object System.Data.SqlClient.SqlConnection
[System.Data.SqlClient.SqlCommand] $cmd = New-Object System.Data.SqlClient.SqlCommand
[System.Data.SqlClient.SqlDataAdapter] $adapter = New-Object System.Data.SqlClient.SqlDataAdapter
[System.Data.DataTable] $dt = New-Object System.Data.DataTable
try {
[string] $connStr = "myConnectionString"
$conn.ConnectionString = $connStr
$cmd.Connection = $conn
$cmd.CommandText = "SELECT * FROM TestTable"
$conn.Open
$adapter.SelectCommand = $cmd
$adapter.Fill($dt)
$conn.Close
}
catch [system.exception]
{
Write-Host $_
}
finally {
$adapter.Dispose
$cmd.Dispose
$conn.Dispose
}
return $dt
}
большая часть функции была удалена для краткости. У меня проблема, когда я вызываю функцию так:
[System.Data.DataTable] $buildData = GetBuildData
Я получаю следующую ошибку:
не удается преобразовать " System.Object [] система "значение типа".Объект[]" для системы типа ".Данные.объект DataTable."
почему Powershell думает, что я хочу вернуть массив object [], когда это очевидно что переменная $dt является DataTable?
EDIT:
Я дважды проверил, и $dt
содержит данные. Например, количество строк.Количество-1, которое ожидается.
4 ответов
Я не знаю о других проблемах, которые люди поднимают, но я могу придумать две возможные причины, почему вы возвращаетесь Object[]
.
-
возможно, у вас есть некаптированный вывод где-то еще в функции. В твоем случае,
Fill
возвращаетint
. Попробуйте добавить это в конец вызовов функций:| Out-Null
Е. Г.,
$adapter.Fill($dt) | Out-Null
если какой-либо оператор возвращает значение, и вы его не фиксируете, вывод будет включен в возвращаемое значение, и поскольку в этот момент у вас будет несколько возвращаемых значений, PowerShell запихнет их все в массив.
-
другая возможность, которая преобразует PowerShell возвращены коллекций всякие в
Object[]
s. Используйте,
оператор для возврата значения unmangled:return , $dt
на
,
создает массив, содержащий только следующее значение. Насколько я могу догадаться, это заставляет PowerShell автоматически разверните внешний массив и оставьте значение в покое, так как фактическое возвращаемое значение теперь является массивом, который содержит только одно значение.на
return
на самом деле является необязательным, так как незахваченные значения включены в возвращаемое значение.только вчера столкнулся с этим сам. Я не могу ни за что на свете понять, почему кто-то думает, что тихо превращается в
Object[]
- это полезно.
У вас есть несколько вопросов в том, что вы опубликовали. Поскольку вы явно создаете объект DataTable с помощью New-Object System.Data.DataTable
, нет причин также принуждать его к типу DataTable с [System.Data.DataTable]
. То же самое верно для вызова функции. Вы возвращаете объект DataTable, так это то, что вы получите обратно. Кроме того, если вы хотите указать тип переменной, между идентификатором типа и именем переменной не должно быть пробела. Несмотря на это, эти проблемы не вызовут поведение, которое вы видите. Я запустил этот код:
function GetBuildData {
$dt = New-Object System.Data.DataTable
$column1 = New-Object system.Data.DataColumn 'Col1'
$column2 = New-Object system.Data.DataColumn 'Col2'
$dt.columns.add($column1)
$dt.columns.add($column2)
$row = $dt.NewRow()
$row.col1 = '1'
$row.col2 = '2'
$dt.rows.add($row)
return $dt
}
$buildData = GetBuildData
$buildData
Col1 Col2
---- ----
1 2
и это сработало просто отлично. Я подозреваю, что бит, который вызывает вашу проблему, вероятно, в бит, который вы исключили для краткости. Ярлыки редко бывают, и вы редко получаете точные ответы от частичных данных.
способствующим фактором является то, что вы фактически не вызываете методы open и close, а ссылаетесь на них вместо этого. PowerShell выводит ссылку на эти методы, а также datatable (который, я полагаю, фактически не заполняется из-за того, что соединение не открыто).
вам нужно включить круглые скобки в методы open/close следующим образом:
$conn.Open()
...
$conn.Close()
вам также нужно остерегаться методов, которые возвращают значения (.Методы Add () печально для этого), что вы не потребляете, назначая переменной или конвейеру out-null.
вам просто нужно аннулировать все ваши команды dot, которые не назначены переменным
function GetBuildData {
[System.Data.SqlClient.SqlConnection] $conn = New-Object System.Data.SqlClient.SqlConnection
[System.Data.SqlClient.SqlCommand] $cmd = New-Object System.Data.SqlClient.SqlCommand
[System.Data.SqlClient.SqlDataAdapter] $adapter = New-Object System.Data.SqlClient.SqlDataAdapter
[System.Data.DataTable] $dt = New-Object System.Data.DataTable
try {
[string] $connStr = "myConnectionString"
$conn.ConnectionString = $connStr
$cmd.Connection = $conn
$cmd.CommandText = "SELECT * FROM TestTable"
[void]$conn.Open
$adapter.SelectCommand = $cmd
$adapter.Fill($dt)
[void]$conn.Close
}
catch [system.exception]
{
Write-Host $_
}
finally {
[void]$adapter.Dispose
[void]$cmd.Dispose
[void]$conn.Dispose
}
$dt
}
что касается вашего вопроса Почему? ... Читайте блог кита Хилла:как вернуть работу функции powershell