Powershell 2.0 — закрытие SqlDataReader при передаче в функцию

Я взаимодействую с набором пользовательских сборок .Net 2.0 с Powershell 2.0 для автоматизации текущей задачи. Я загружаю все необходимые dll и вызываю метод DAL в dll для получения 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)

Читатель $reader открыт и имеет данные до того, как я вызову конструктор Thing.

Я должен что-то упустить, но я не уверен, что именно.

Редактировать 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)

person Jared314    schedule 11.01.2011    source источник


Ответы (1)


Я столкнулся с подобными проблемами некоторое время назад. Посмотрите на этот код:

Я создаю свой собственный 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 все равно попытается получить перечислитель и творить магию.

person stej    schedule 11.01.2011
comment
Похоже, это относится к SqlDataReader. Есть ли способ предотвратить это? - person Jared314; 11.01.2011
comment
Похоже, мне нужно обернуть его в другой массив, потому что нет никакого способа предотвратить это. - person Jared314; 11.01.2011