Добавление компонентов потока данных программным образом
Построение потока данных начинается с добавления компонентов. Затем необходимо настроить эти компоненты и соединить их друг с другом, чтобы образовался поток данных времени выполнения. В этом разделе описывается добавление компонента в задачу потока данных, создание экземпляра компонента времени разработки и последующая настройка компонента. Сведения о том, как соединить компоненты, см. в разделе Программное соединение компонентов потока данных.
Добавление компонента
Вызовите метод New коллекции ComponentMetaDataCollection, чтобы создать новый компонент и добавить его в задачу потока данных. Этот метод возвращает интерфейс IDTSComponentMetaData100 компонента. Однако на этом этапе интерфейс IDTSComponentMetaData100 не содержит сведений, относящихся к какому-либо определенному компоненту. Задайте свойство ComponentClassID, чтобы определить тип компонента. Задача потока данных использует значение этого свойства для создания экземпляра компонента во время выполнения.
Значение, указанное в свойстве ComponentClassID, может обозначать идентификатор CLSID, PROGID или свойство CreationName компонента. Идентификатор CLSID обычно отображается в окне «Свойства» как значение свойства ComponentClassID компонента. Сведения о получении значений этого свойства и других свойств доступных компонентов см. в разделе Программный поиск компонентов потока данных.
Добавление управляемого компонента
Использовать идентификаторы CLSID или PROGID для добавления управляемых компонентов потока данных в поток данных нельзя, поскольку эти значения указывают на оболочку, а не на сам компонент. Вместо этого можно использовать свойство CreationName или свойство AssemblyQualifiedName, как показано в следующем образце.
Если необходимо использовать свойство AssemblyQualifiedName, следует добавить в проект Visual Studio ссылку на сборку, содержащую управляемый компонент. Эти сборки отсутствуют в списке на вкладке «.NET» диалогового окна Добавление ссылки. Обычно необходимо указать расположение сборки в папке C:\Program Files\Microsoft SQL Server\100\DTS\PipelineComponents.
В число встроенных управляемых компонентов потока данных входят:
Источник ADO.NET
XML-источник
Назначение DataReader
Назначение SQL Server Compact
Компонент скрипта
В следующем образце кода демонстрируются оба способа добавления управляемого компонента в поток данных:
using System;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
namespace Microsoft.SqlServer.Dts.Samples
{
class Program
{
static void Main(string[] args)
{
Microsoft.SqlServer.Dts.Runtime.Package package = new Microsoft.SqlServer.Dts.Runtime.Package();
Executable e = package.Executables.Add("STOCK:PipelineTask");
Microsoft.SqlServer.Dts.Runtime.TaskHost thMainPipe = (Microsoft.SqlServer.Dts.Runtime.TaskHost)e;
MainPipe dataFlowTask = (MainPipe)thMainPipe.InnerObject;
// The Application object will be used to obtain the CreationName
// of a PipelineComponentInfo from its PipelineComponentInfos collection.
Application app = new Application();
// Add a first ADO NET source to the data flow.
// The CreationName property requires an Application instance.
IDTSComponentMetaData100 component1 = dataFlowTask.ComponentMetaDataCollection.New();
component1.Name = "DataReader Source";
component1.ComponentClassID = app.PipelineComponentInfos["DataReader Source"].CreationName;
// Add a second ADO NET source to the data flow.
// The AssemblyQualifiedName property requires a reference to the assembly.
IDTSComponentMetaData100 component2 = dataFlowTask.ComponentMetaDataCollection.New();
component2.Name = "DataReader Source";
component2.ComponentClassID = typeof(Microsoft.SqlServer.Dts.Pipeline.DataReaderSourceAdapter).AssemblyQualifiedName;
}
}
}
Imports Microsoft.SqlServer.Dts.Runtime
Imports Microsoft.SqlServer.Dts.Pipeline
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Module Module1
Sub Main()
Dim package As Microsoft.SqlServer.Dts.Runtime.Package = _
New Microsoft.SqlServer.Dts.Runtime.Package()
Dim e As Executable = package.Executables.Add("STOCK:PipelineTask")
Dim thMainPipe As Microsoft.SqlServer.Dts.Runtime.TaskHost = _
CType(e, Microsoft.SqlServer.Dts.Runtime.TaskHost)
Dim dataFlowTask As MainPipe = CType(thMainPipe.InnerObject, MainPipe)
' The Application object will be used to obtain the CreationName
' of a PipelineComponentInfo from its PipelineComponentInfos collection.
Dim app As New Application()
' Add a first ADO NET source to the data flow.
' The CreationName property requires an Application instance.
Dim component1 As IDTSComponentMetaData100 = _
dataFlowTask.ComponentMetaDataCollection.New()
component1.Name = "DataReader Source"
component1.ComponentClassID = app.PipelineComponentInfos("DataReader Source").CreationName
' Add a second ADO NET source to the data flow.
' The AssemblyQualifiedName property requires a reference to the assembly.
Dim component2 As IDTSComponentMetaData100 = _
dataFlowTask.ComponentMetaDataCollection.New()
component2.Name = "DataReader Source"
component2.ComponentClassID = _
GetType(Microsoft.SqlServer.Dts.Pipeline.DataReaderSourceAdapter).AssemblyQualifiedName
End Sub
End Module
Создание экземпляра компонента времени разработки
Вызовите метод Instantiate, чтобы создать экземпляр компонента времени разработки, определенный свойством ComponentClassID. Этот метод возвращает объект CManagedComponentWrapper, который является управляемой оболочкой для интерфейса IDTSDesigntimeComponent100.
При возможности для изменения компонента следует использовать методы экземпляра времени разработки, а не изменять непосредственно метаданные компонента. Хотя некоторые элементы метаданных, например соединения, необходимо задавать непосредственно, обычно не рекомендуется изменять метаданные непосредственно, поскольку при этом не задействуются возможности компонента по отслеживанию и проверке изменений.
Назначение соединений
Для некоторых компонентов, например, компонента «Источник OLE DB», требуется соединение с внешним источником данных. Для этой цели используется существующий в пакете объект ConnectionManager. Значение свойства Count коллекции RuntimeConnectionCollection указывает на число объектов ConnectionManager, необходимых для компонента. Если это число больше нуля, для компонента требуется соединение. Назначьте для компонента диспетчер соединений из пакета, указав свойства ConnectionManager и Name первого соединения в коллекции RuntimeConnectionCollection. Обратите внимание на то, что имя диспетчера соединений в коллекции соединений времени выполнения должно совпадать с именем диспетчера соединений,на который ссылается пакет.
Задание значений пользовательских свойств
После создания экземпляра компонента времени разработки, вызовите метод ProvideComponentProperties. Этот метод подобен конструктору, поскольку он инициализирует только что созданный компонент, создавая его пользовательские свойства, а также объекты входа и выхода. Нельзя вызывать метод ProvideComponentProperties более одного раза для компонента, поскольку при этом могут быть сброшены настройки компонента и потеряны все изменения, ранее внесенные в его метаданные.
Коллекция свойств CustomPropertyCollection компонента содержит коллекцию объектов IDTSCustomProperty100, относящихся к компоненту. В отличие от других моделей программирования, где свойства объекта всегда доступны для объекта, компоненты заполняют свои коллекции пользовательских свойств только при вызове метода ProvideComponentProperties. После вызова этого метода используйте метод SetComponentProperty экземпляра компонента времени разработки, чтобы присвоить значения его пользовательским свойствам. Этот метод принимает пару имя-значение, идентифицирующую пользовательское свойство, и возвращает ее новое значение.
Инициализация выходных столбцов
После добавления компонента в задачу и его настройки инициализируйте коллекцию столбцов в свойстве IDTSOutput100 объекта. Этот шаг имеет непосредственное отношение к компоненту-источнику, однако для компонентов преобразования и назначения может не инициализировать столбцы, поскольку они, как правило, зависят от столбцов, получаемых из вышестоящих компонентов.
Вызовите метод ReinitializeMetaData, чтобы инициализировать столбцы на выходах компонента-источника. Так как компоненты не соединяются автоматически с внешними источниками данных, необходимо вызвать метод AcquireConnections перед вызовом метода ReinitializeMetaData, чтобы обеспечить компоненту доступ к его внешнему источнику данных и возможность заполнить метаданными соответствующий столбец. Наконец, следует вызвать метод ReleaseConnections, чтобы освободить соединение.
Следующий шаг
После добавления и настройки компонента следующим шагом является создание путей между компонентами, которое рассматривается в разделе Создание пути между двумя компонентами.
Образец
В следующем образце кода компонент «Источник OLE DB» добавляется в задачу потока данных, создается экземпляр компонента времени разработки и выполняется настройка свойств компонента. Для этого образца необходима дополнительная ссылка на сборку Microsoft.SqlServer.DTSRuntimeWrap.
using System;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
namespace Microsoft.SqlServer.Dts.Samples
{
class Program
{
static void Main(string[] args)
{
Runtime.Package package = new Runtime.Package();
Executable e = package.Executables.Add("STOCK:PipelineTask");
Runtime.TaskHost thMainPipe = e as Runtime.TaskHost;
MainPipe dataFlowTask = thMainPipe.InnerObject as MainPipe;
// Add an OLEDB connection manager to the package.
ConnectionManager cm = package.Connections.Add("OLEDB");
cm.Name = "OLEDB ConnectionManager";
cm.ConnectionString = "Data Source=(local);" +
"Initial Catalog=AdventureWorks;Provider=SQLOLEDB.1;" +
"Integrated Security=SSPI;"
// Add an OLE DB source to the data flow.
IDTSComponentMetaData100 component =
dataFlowTask.ComponentMetaDataCollection.New();
component.Name = "OLEDBSource";
component.ComponentClassID = "DTSAdapter.OleDbSource.1";
// You can also use the CLSID of the component instead of the PROGID.
//component.ComponentClassID = "{2C0A8BE5-1EDC-4353-A0EF-B778599C65A0}";
// Get the design time instance of the component.
CManagedComponentWrapper instance = component.Instantiate();
// Initialize the component
instance.ProvideComponentProperties();
// Specify the connection manager.
if (component.RuntimeConnectionCollection.Count > 0)
{
component.RuntimeConnectionCollection[0].ConnectionManager =
DtsConvert.GetExtendedInterface(package.Connections[0]);
component.RuntimeConnectionCollection[0].ConnectionManagerID =
package.Connections[0].ID; }
// Set the custom properties.
instance.SetComponentProperty("AccessMode", 2);
instance.SetComponentProperty("SqlCommand",
"Select * from Production.Product");
// Reinitialize the metadata.
instance.AcquireConnections(null);
instance.ReinitializeMetaData();
instance.ReleaseConnections();
// Add other components to the data flow and connect them.
}
}
}
Imports Microsoft.SqlServer.Dts.Runtime
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper
Imports Microsoft.SqlServer.Dts.Pipeline
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Module Module1
Sub Main()
Dim package As Microsoft.SqlServer.Dts.Runtime.Package = _
New Microsoft.SqlServer.Dts.Runtime.Package()
Dim e As Executable = package.Executables.Add("STOCK:PipelineTask")
Dim thMainPipe As Microsoft.SqlServer.Dts.Runtime.TaskHost = _
CType(e, Microsoft.SqlServer.Dts.Runtime.TaskHost)
Dim dataFlowTask As MainPipe = CType(thMainPipe.InnerObject, MainPipe)
' Add an OLEDB connection manager to the package.
Dim cm As ConnectionManager = package.Connections.Add("OLEDB")
cm.Name = "OLEDB ConnectionManager"
cm.ConnectionString = "Data Source=(local);" & _
"Initial Catalog=AdventureWorks;Provider=SQLOLEDB.1;" & _
"Integrated Security=SSPI;"
' Add an OLE DB source to the data flow.
Dim component As IDTSComponentMetaData100 = _
dataFlowTask.ComponentMetaDataCollection.New()
component.Name = "OLEDBSource"
component.ComponentClassID = "DTSAdapter.OleDbSource.1"
' You can also use the CLSID of the component instead of the PROGID.
'component.ComponentClassID = "{2C0A8BE5-1EDC-4353-A0EF-B778599C65A0}";
' Get the design time instance of the component.
Dim instance As CManagedComponentWrapper = component.Instantiate()
' Initialize the component.
instance.ProvideComponentProperties()
' Specify the connection manager.
If component.RuntimeConnectionCollection.Count > 0 Then
component.RuntimeConnectionCollection(0).ConnectionManager = _
DtsConvert.GetExtendedInterface(package.Connections(0))
component.RuntimeConnectionCollection(0).ConnectionManagerID = _
package.Connections(0).ID
End If
' Set the custom properties.
instance.SetComponentProperty("AccessMode", 2)
instance.SetComponentProperty("SqlCommand", _
"Select * from Production.Product")
' Reinitialize the metadata.
instance.AcquireConnections(vbNull)
instance.ReinitializeMetaData()
instance.ReleaseConnections()
' Add other components to the data flow and connect them.
End Sub
End Module
Внешние ресурсы
Запись в блоге: EzAPI – Updated for SQL Server 2012, на сайте blogs.msdn.com.
|