function Main {
$result1 = DoWork1
$result1.GetType()
$result2 = DoWork2
$result2.GetType()
}
function DoWork1 {
$result1 = Invoke-Sqlcmd -Query "select top 1 * from customer" -ServerInstance "(localdb)\MSSQLLocalDB" -Database "Database1" -OutputAs DataTables
#assign to variable then return
return $result1
}
function DoWork2 {
#return results without assigning to variable
return Invoke-Sqlcmd -Query "select top 1 * from customer" -ServerInstance "(localdb)\MSSQLLocalDB" -Database "Database1" -OutputAs DataTables
}
Main
Run Code Online (Sandbox Code Playgroud)
这是意外的输出:
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False DataRow System.Object
True True DataTable System.ComponentModel.MarshalByValueComponent
Run Code Online (Sandbox Code Playgroud)
使用之前的问答中的类似示例来重现相同的行为:
function Invoke-SqlExample {
$dtt = [System.Data.DataTable]::new()
[void] $dtt.Columns.Add('Name')
$row = $dtt.NewRow()
$row.Name = "Hello"
$dtt.Rows.Add($row)
, $dtt
}
function Main {
$result1 = DoWork1
$result1.GetType()
$result2 = DoWork2
$result2.GetType()
}
function DoWork1 {
$result1 = Invoke-SqlExample
[pscustomobject]@{
Function = $MyInvocation.MyCommand.Name
Type = $result1.GetType().Name
} | Out-Host
return $result1
# Immediate fixes:
# return , $result1
# Write-Output $result1 -NoEnumerate
# $PSCmdlet.WriteObject($result1, $false) !! Only if Advanced Function
}
function DoWork2 {
return Invoke-SqlExample
}
Main
Run Code Online (Sandbox Code Playgroud)
您将从中得到的输出是:
Function Type
-------- ----
DoWork1 DataTable
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False DataRow System.Object
True True DataTable System.ComponentModel.MarshalByValueComponent
Run Code Online (Sandbox Code Playgroud)
我们可以看到,只有在先前分配给变量时才会展开 the DataTable,即使该变量($result1inDoWork1仍然是类型DataTable)。
这可以解释为,DoWork2发生在单个管道中而不是DoWork1发生在两个管道中,首先Invoke-SqlExample将输出收集在变量中,然后作为输出发出(这是触发展开的地方)。这是基于假设,可能不完全正确。
正如iRon 在先前答案中的有用评论中建议的那样,立即修复以不受影响地DoWork1返回DataTable实例(展开),我们可以使用逗号运算符,,它将DataTable实例包装在一个数组中,然后在枚举期间丢失该实例(函数的输出) ),因为它是一个只有一个元素的数组。另一种选择是使用Write-Output -NeEnumerate. 作为最后一种选择,我们也可以仅在该功能是高级功能时使用。$PSCmdlet.WriteObject(..., $false)
添加一个演示相同行为的类似示例,该示例由mclayton 在他的有用评论中提供:
function test {
, [Collections.Generic.List[string]]@(
'hello'
'world'
)
}
(& { test }).GetType() # => List`1
(& { $a = test; $a }).GetType() # => Object[]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
151 次 |
| 最近记录: |