以编程方式添加数据流组件
若要生成数据流,则可以先添加组件。然后配置这些组件并将它们连接在一起,以便在运行时建立数据流。本节将介绍如何向数据流任务添加组件、如何创建组件的设计时实例以及配置该组件。有关如何连接组件的信息,请参阅以编程方式连接数据流组件。
添加组件
对 ComponentMetaDataCollection 集合调用 New 方法可创建新组件并将其添加到数据流任务。此方法将返回组件的 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 对象来实现此分配目的。RuntimeConnectionCollection 集合的 Count 属性指示组件所需的运行时 ConnectionManager 对象的数量。如果该计数大于零,则组件需要连接。可通过指定 RuntimeConnectionCollection 中的第一个连接的 ConnectionManager 和 Name 属性,将包中的连接管理器分配给组件。请注意,运行时连接集合中的连接管理器的名称必须与从包中引用的连接管理器的名称匹配。
设置自定义属性的值
创建组件的设计时实例后,可调用 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
|