.net – Powershell Receive-Job可以返回一个DataSet吗?

背景资料:

我有一个应用程序,它与多个数据库建立了几个SQL连接,这些数据库目前需要很长时间才能执行.

Powershell(.NET)将等待每个正在进行的“SQL-GET”功能完成,然后才能触发下一个.我的印象是我可以通过在他们自己的后台作业中同时触发每个“SQL-GET”功能来大大提高这个应用程序!然后我将在每个作业完成时检索数据.理想情况下,作为DataSet系统对象.

问题:

从后台作业中检索数据时,我只能设法获取System.Array对象.我实际上是一个System.DataSet对象.这是必要的,因为应用程序中的所有逻辑都依赖于DataSet对象.

代码:

这是一个v.simple代码片段,它将创建一个sql连接并用返回的结果填充一个新创建的数据集对象.工作一种享受. $results是一个DataSet对象,我可以很好地操作它.

$query = "SELECT * FROM [database]..[table] WHERE column = '123456'"

$Connection = New-Object System.Data.SqlClient.SQLConnection      
$ConnectionString = "Server='SERVER';Database='DATABASE';User ID='SQL_USER';Password='SQL_PASSWORD'"  
$Connection.ConnectionString = $ConnectionString     
$Connection.Open() 
$Command = New-Object system.Data.SqlClient.SqlCommand($Query,$Connection) 
$Adapter = New-Object system.Data.SqlClient.SqlDataAdapter
$Adapter.SelectCommand = $Command
$Connection.Close() 
[System.Data.SqlClient.SqlConnection]::ClearAllPools()

$results = New-Object system.Data.DataSet 

[void]$Adapter.fill($results)

$results.Tables[0]

这里是非常相同的代码包装到新后台作业的scriptblock参数中.只有在调用Receive-Job时,才会返回数组,而不是数据集.

     $test_job = Start-Job -ScriptBlock {

$query = "SELECT * FROM [database]..[table] WHERE column = '123456'"

$Connection = New-Object System.Data.SqlClient.SQLConnection      
$ConnectionString = "Server='SERVER';Database='DATABASE';User ID='SQL_USER';Password='SQL_PASSWORD'"  
$Connection.ConnectionString = $ConnectionString     
$Connection.Open() 
$Command = New-Object system.Data.SqlClient.SqlCommand($Query,$Connection) 
$Adapter = New-Object system.Data.SqlClient.SqlDataAdapter
$Adapter.SelectCommand = $Command
$Connection.Close() 
[System.Data.SqlClient.SqlConnection]::ClearAllPools()

$results = New-Object system.Data.DataSet 

[void]$Adapter.fill($results) 
return $results.Tables[0]

}

Wait-Job $test_job
$ret_results = Receive-Job $test_job

任何帮助将不胜感激!!!

迄今为止的研究:

我已经完成了旧的谷歌,但我偶然发现的所有帖子,博客和文章似乎都进入了关于管理工作以及围绕这个问题的所有花哨的深度.仅通过receive-job cmdlet返回数组是PowerShell的基本特性吗?

我已经阅读了关于返回表达式的stack post.以为我接受了一些事情.尝试:

> return $results.Tables [0]
> return,$results.Tables [0]
>返回,​​$结果

所有仍然返回一个数组.

我已经看到人们,相当繁琐,手动将数组转换回数据集对象 – 虽然这看起来非常’肮脏’ – 我很迂腐,希望必须有一种方法让这个神奇的数据集对象遍历后台工作和进入我当前的会议! 🙂

重申:

基本上,我想要的是将从Rece-Job cmdlet中检索到的$ret_results对象作为DataSet …甚至是DataTable.我会采取…不是一个阵列:)

最佳答案 在powershell中,一组多个任意类型的对象在集合中返回是很常见的.考虑这个改变的例子,我构建自己的表:

PS C:\> $job = Start-Job -ScriptBlock {
>>
>> $table = New-Object system.Data.DataTable “MyTable”
>>
>> $col1 = New-Object system.Data.DataColumn MyFirstCol,([string])
>> $col2 = New-Object system.Data.DataColumn MyIntCol,([int])
>>
>> $table.columns.add($col1)
>> $table.columns.add($col2)
>>
>> $row1 = $table.NewRow()
>> $row1.MyFirstCol = "FirstRow"
>> $row1.MyIntCol = 1
>> $row2 = $table.NewRow()
>> $row2.MyFirstCol = "SecondRow"
>> $row2.MyIntCol = 2
>>
>> $table.Rows.Add($row1)
>> $table.Rows.Add($row2)
>>
>> $dataSet = New-Object system.Data.DataSet
>> $dataSet.Tables.Add($table)
>>
>> $dataSet.Tables[0]
>>
>> }
>>
PS C:\> $output = Receive-Job -Job $job

收到的输出.那我们得到了什么?

PS C:\> $output.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

正如你所描述的那样一个数组.但这就是整个对象.如果我们通过将它们分配给Get-Member来单独分析其成员,该怎么办?

PS C:\> $output | gm

   TypeName: Deserialized.System.Data.DataRow

Name               MemberType   Definition
----               ----------   ----------
ToString           Method       string ToString(), string ToString(string format, System.IFormatProvider formatProvi...
PSComputerName     NoteProperty System.String PSComputerName=localhost
PSShowComputerName NoteProperty System.Boolean PSShowComputerName=False
RunspaceId         NoteProperty System.Guid RunspaceId=186c51c3-d3a5-404c-9a4a-8ff3d3a7f024
MyFirstCol         Property     System.String {get;set;}
MyIntCol           Property     System.Int32 {get;set;}

PS C:\> $output


RunspaceId : 186c51c3-d3a5-404c-9a4a-8ff3d3a7f024
MyFirstCol : FirstRow
MyIntCol   : 1

RunspaceId : 186c51c3-d3a5-404c-9a4a-8ff3d3a7f024
MyFirstCol : SecondRow
MyIntCol   : 2

考虑以下:

>在您的工作中,您已指定$results.Tables [0]应返回.通过指定特定的表迭代,您将返回描述该表的对象…可能是DataTable,或者在这种情况下是DataRows …而不是像您似乎期待的DataSet?
> DataTables有行.如果DataTable有多行,那么powershell会在DataRows集合中返回它,正如我在上面演示的那样.您可能会惊讶地发现,返回单行不是这种情况 – 它只返回单个DataRow对象而不是DataRow对象的集合.
>如果这确实是您期望的输出,您可能希望通过将输出指定为@($results.Tables [0])来强制它始终在集合中返回.这样,您总是知道期望一个集合并且可以适当地处理结果内容(通过迭代集合来管理单个对象).

点赞