2017-07-24 59 views
4

我有一個Powershell函數調用存儲過程,並通過調用ExecuteReader完成。這返回一個對象,然後我傳遞給另一個函數。看起來該對象的類型在該過程中的某處發生了變化。我懷疑我正打算在某處無意中調用某種方法。無法從一個函數返回對象並將其傳遞給另一個

我修整我的腳本到這一點:

Param(
    [string] $DatabaseHost, 
    [int32] $RunA, 
    [int32] $RunB 
) 

Set-StrictMode -Version Latest 
$ErrorActionPreference = 'Stop' 

# This function works as expected. 
Function New-DatabaseConnection { 
    Param(
     [string] $databaseHost 
    ) 
    $connectionProperties = @{} 
    $connectionProperties.ConnectionString = "Server=$databaseHost;Database=fitbit;Integrated Security=True" 
    $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection -Property $connectionProperties 
    $connection.Open() 
    return $connection 
} 

Function Invoke-StoredProcedure { 
    Param(
     [int32] $runA, 
     [int32] $runB 
    ) 
    $command = $connection.CreateCommand() 
    $command.CommandType = [System.Data.CommandType] 'StoredProcedure' 
    $command.CommandText = 'analysis.compareRunsWithSameInputs' 
    [void] $command.Parameters.Add('@runA', $runA) 
    [void] $command.Parameters.Add('@runB', $runB) 
    return $command.ExecuteReader() # What happens between here and the call to Write-ResultSetToSheet? 
} 

Function Write-ResultSetToSheet { 
    Param(
     [System.Data.SqlClient.SqlDataReader] $reader 
    ) 
    # The body of this function is irrelevant, because we don't get this far. 
    [void] $reader.Read() 
    Write-Output $reader.GetString(0) 
} 

$connection = New-DatabaseConnection $DatabaseHost 
try { 
    $reader = Invoke-StoredProcedure $RunA $RunB 
    Write-ResultSetToSheet $reader # This fails, because somehow the type of $reader has changed from SqlDataReader to DataRecordInternal. 
} finally { 
    $connection.Close() 
} 

當我執行此,我得到這個錯誤:

Write-ResultSetToSheet : Cannot process argument transformation on parameter 'reader'. Cannot convert the "System.Data.Common.DataRecordInternal" value of type "System.Data.Common.DataRecordInternal" to type "System.Data.SqlClient.SqlDataReader". 
At C:\dev\ps1\Invoke-SoTest.ps1:45 char:28 
+  Write-ResultSetToSheet $reader 
+       ~~~~~~~ 
    + CategoryInfo   : InvalidData: (:) [Write-ResultSetToSheet], ParentContainsErrorRecordException 
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Write-ResultSetToSheet 

合併這兩個功能的工作原理,但:

... 
[void] $command.Parameters.Add('@runB', $runB) 
$reader = $command.ExecuteReader() 
Write-Output $reader.GetType() # I'm using this to check the type of the object. See below for more details. 
[void] $reader.Read() 
Write-Output $reader.GetString(0) 

這是從Write-Output $reader.GetType()的輸出:

IsPublic IsSerial Name          BaseType                                                
-------- -------- ----          --------                                                
True  False SqlDataReader       System.Data.Common.DbDataReader 

(注意,從System.Data.SqlClient.SqlDataReader改變聲明的類型的$reader參數來System.Data.Common.DbDataReader沒有幫助。)

我是一個有經驗的開發人員,但新的.NET和很新的PowerShell的。

回答

5

從函數返回時,Powershell有時會嘗試展開對象。要強制Powershell不展開對象,請在返回的變量前使用逗號,return ,$myVar

這應該有助於在各個函數之間移動對象。您可能還需要確保你如果PowerShell是有一個很難確定的對象類型強類型的對象,(例如,[int]$myInt = 7

另見Powershell Operators以獲取更多信息。

相關問題