Написание кода пользовательского перечислителя по каждому элементу
После создания класса, наследующего базовый класс ForEachEnumerator, и применения к нему атрибута DtsForEachEnumeratorAttribute необходимо переопределить реализацию свойств и методов базового класса, чтобы обеспечить пользовательские функциональные возможности.
Рабочий образец пользовательского перечислителя см. в образцах служб Integration Services в разделе Codeplex.
Инициализация перечислителя
Метод InitializeForEachEnumerator можно переопределить для кэширования ссылок на диспетчеры соединений, определенные в пакете, и на интерфейс событий, который можно использовать для формирования ошибок, предупреждений и информационных сообщений.
Проверка перечислителя
Метод Validate переопределяется для проверки правильности настройки перечислителя. Если этот метод возвращает значение Failure, то перечислитель не будет выполнен в содержащем его пакете. Реализация данного метода индивидуальна для каждого перечислителя, но если перечислитель опирается на объект Variable или ConnectionManager, то необходимо добавить код для проверки наличия этих объектов в коллекции, переданной методу.
Следующий пример кода иллюстрирует реализацию метода Validate, который проверяет переменную, указанную в свойстве перечислителя.
private string variableNameValue;
public string VariableName
{
get{ return this.variableNameValue; }
set{ this.variableNameValue = value; }
}
public override DTSExecResult Validate(Connections connections, VariableDispenser variableDispenser, IDTSInfoEvents infoEvents, IDTSLogging log)
{
if (!variableDispenser.Contains(this.variableNameValue))
{
infoEvents.FireError(0, "MyEnumerator", "The Variable " + this.variableNameValue + " does not exist in the collection.", "", 0);
return DTSExecResult.Failure;
}
return DTSExecResult.Success;
}
Private variableNameValue As String
Public Property VariableName() As String
Get
Return Me.variableNameValue
End Get
Set (ByVal Value As String)
Me.variableNameValue = value
End Set
End Property
Public Overrides Function Validate(ByVal connections As Connections, ByVal variableDispenser As VariableDispenser, ByVal infoEvents As IDTSInfoEvents, ByVal log As IDTSLogging) As DTSExecResult
If Not variableDispenser.Contains(Me.variableNameValue) Then
infoEvents.FireError(0, "MyEnumerator", "The Variable " + Me.variableNameValue + " does not exist in the collection.", "", 0)
Return DTSExecResult.Failure
End If
Return DTSExecResult.Success
End Function
Возврат коллекции
В процессе выполнения контейнер ForEachLoop вызывает метод пользовательского перечислителя GetEnumerator. В этом методе перечислитель создает и заполняет коллекцию элементов, после чего возвращает эту коллекцию. Затем объект ForEachLoop последовательно перебирает элементы коллекции и выполняет поток управления для каждого элемента коллекции.
Следующий пример иллюстрирует реализацию метода GetEnumerator, который возвращает массив случайных значений.
public override object GetEnumerator()
{
ArrayList numbers = new ArrayList();
Random randomNumber = new Random(DateTime.Now);
for( int x=0; x < 100; x++ )
numbers.Add( randomNumber.Next());
return numbers;
}
Public Overrides Function GetEnumerator() As Object
Dim numbers As ArrayList = New ArrayList()
Dim randomNumber As Random = New Random(DateTime.Now)
Dim x As Integer
For x = 0 To 100- 1 Step x + 1
numbers.Add(randomNumber.Next())
Next
Return numbers
End Function
|