我正在使用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)
在我调用Thing构造函数之前,$ reader是打开的,并且有数据。
我必须遗漏一些东西,但我不确定它是什么。
修改1:
$ reader无论何时传递给函数,PowerShell或程序集中,都会被读取并关闭。有办法防止这种情况吗?
编辑2:
Powershell自动展开再次打击
How to stop PowerShell from unpacking an Enumerable object?
Strange behavior in PowerShell function returning 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)
答案 0 :(得分:5)
前段时间我遇到过类似的问题。看看这段代码:
我创建了自己的Enumerator,它会打印一些有关何时调用它的信息。它与SqlDataReader
相同(我认为)也会实现IEnumerator
。
PS> Add-Type -TypeDefinition @"
using System;
using System.Collections;
public class MyEnumerator2 : IEnumerator
{
private int _count = 10;
private Random r = new Random();
public MyEnumerator2(int count)
{
_count = count;
}
public bool MoveNext()
{
Console.WriteLine("Moving!");
_count--;
return _count >= 0;
}
public void Reset()
{
throw new NotImplementedException();
}
public object Current
{
get
{
Console.WriteLine("Current!");
return r.Next();
}
}
}
"@
然后让我们创建一个该类型的对象并尝试输出它:
PS> $mye = New-Object MyEnumerator2 5
PS> $mye | % -begin { write-host 'starting' } -Process { write-host 'next is ' $_ }
starting
Moving!
Current!
next is 2081278528
Moving!
Current!
next is 2000135673
Moving!
Current!
next is 692162542
Moving!
Current!
next is 1531746038
Moving!
Current!
next is 1550381634
Moving!
一切都如预期。但是......现在
PS> function iteratemye($o) {
$o | % -begin { write-host 'starting' } -Process { write-host 'next is ' $_ }
}
PS> $mye = New-Object MyEnumerator2 5
PS> iteratemye $mye
Moving!
Current!
Moving!
Current!
Moving!
Current!
Moving!
Current!
Moving!
Current!
Moving!
starting
Moving!
如果将此枚举器传递给函数,则在它到达正文之前将其读为。那非常糟糕。
所以看看你的代码。如果你使用像iteratemye
这样的函数,那就是你的问题的原因。
更新:它不会实现IEnumerator
,而是IEnumerable
。
我看到你只是将对象传递给一些构造函数,这与我遇到的问题不同,但我相信PowerShell仍然会尝试获取枚举器并做一些魔术。