这真让我抓狂.我有一个来自多个脚本的库,它包含以下功能:
function lib_open_dataset([string] $sql) {
$ds = new-object "System.Data.DataSet"
$da = new-object "System.Data.SqlClient.SqlDataAdapter" ($sql, $_conn_string)
$record_count = $da.Fill($ds)
return $ds
}
Run Code Online (Sandbox Code Playgroud)
这几乎被称为无处不在,它工作得很好,除了我通常必须这样做:
$ds = lib_open_dataset($some_sql)
$table = $ds.Tables[0]
foreach ($row in $table.Rows) {
# etc
}
Run Code Online (Sandbox Code Playgroud)
所以我创建了一个新的简单包装函数,以避免解除引用第一个表的额外步骤:
function lib_open_table([string] $sql) {
$ds = lib_open_dataset $sql
return $ds.Tables[0]
}
Run Code Online (Sandbox Code Playgroud)
问题是,从这里返回的是由于某种原因而不是表本身的表的Rows集合.这会导致上面写的行循环失败并显示"无法索引到空数组".例外.经过多次试验和错误,我发现这是有效的:foreach
foreach ($row in $table) {
# etc
}
Run Code Online (Sandbox Code Playgroud)
需要注意的区别$table.Rows,只是$table在foreach声明.这有效.因为$table实际上指向Rows集合.如果声明
return $ds.Tables[0]
Run Code Online (Sandbox Code Playgroud)
假设是正确的,为什么函数返回表对象的子集合而不是表本身?
我猜测Powershell功能的工作原理显然会引起这种情况,但我无法弄清楚是什么.
我正在与一组使用Powershell 2.0的自定义.Net 2.0程序集进行交互,以自动执行当前任务.我加载所有必需的dll并在dll中调用DAL方法来检索System.Data.SqlDataReader.当我将SqlDataReader传递到同一个自定义程序集中的构造函数时,我收到"在读取器关闭时无效尝试调用HasRows".例外.
代码示例:
dir D:\stuff\*.dll | foreach { [Reflection.Assembly]::LoadFrom($_.FullName) } | out-null
[CustomAssembly.DataConfig]::ConnectionString = "Valid Connection String"
$reader=[CustomAssembly.DAL.Thing]::Get(123)
new-object CustomAssembly.BusinessObjects.Thing($reader)
Run Code Online (Sandbox Code Playgroud)
在我调用Thing构造函数之前,$ reader是打开的,并且有数据.
我必须遗漏一些东西,但我不确定它是什么.
编辑1:
$ reader在传递给函数,powershell或程序集中的任何时候似乎都被读取和关闭.有办法防止这种情况吗?
编辑2:
Powershell自动展开再次打击
如何阻止PowerShell解压缩Enumerable对象?
PowerShell函数中的奇怪行为返回DataSet/DataTable
以下修改的代码示例通过将结果包装在单个元素数组中来工作,因此自动展开不会影响SqlDataReader.请注意"$ reader ="语句后面的单个逗号.那不是拼写错误.
dir D:\stuff\*.dll | foreach { [Reflection.Assembly]::LoadFrom($_.FullName) } | out-null
[CustomAssembly.DataConfig]::ConnectionString = "Valid Connection String"
$reader=,[CustomAssembly.DAL.Thing]::Get(123)
new-object CustomAssembly.BusinessObjects.Thing($reader)
Run Code Online (Sandbox Code Playgroud)