开发SSIS自定义组件:PreExecute方法无法获取连接管理器
开发Salesforce SSIS自定义源组件遇到的连接空引用问题
我正在开发一个从Salesforce获取数据的SSIS自定义源组件,自定义连接管理器已验证可用。组件在执行到PreExecute方法前都能正常获取连接,但进入PreExecute后,断点无法生效,用MessageBox.Show()调试发现连接变量sfConnection和ksConnectionManager被重置为null。不过在SetComponentProperty方法执行阶段,连接管理器和组件都能正常工作,我可以向SSIS包中添加输出列。当尝试在PreExecute中处理SSIS Outputs(OutputCollection)时,触发了空引用异常。
报错信息
[MyCustomComponent Source [8]] Error: System.NullReferenceException: Object reference not set to an instance of an object.
at MyCustomComponent.MyCustomComponentSource.MyCustomComponentSource.PreExecute()
at Microsoft.SqlServer.Dts.Pipeline.ManagedComponentHost.HostPreExecute(IDTSManagedComponentWrapper100 wrapper)
组件代码
[DtsPipelineComponent(DisplayName = "MyCustomComponent", ComponentType = ComponentType.SourceAdapter, IconResource = "MyCustomComponent.Resources.Icon1.ico")] public class MyCustomComponent : PipelineComponent { private ForceClient sfConnection; private SFConnectionManager.SFConnectionManager ksConnectionManager; private string sfQuery = string.Empty; //private string sfQuery = "SELECT id, name, AccountNumber, BillingCity FROM Account"; public int[] mapOutputColsToBufferCols; public override void AcquireConnections(object transaction) { //base.AcquireConnections(transaction); if (ComponentMetaData.RuntimeConnectionCollection[0].ConnectionManager != null) { ConnectionManager connectionManager = Microsoft.SqlServer.Dts.Runtime.DtsConvert.GetWrapper( ComponentMetaData.RuntimeConnectionCollection[0].ConnectionManager); this.ksConnectionManager = connectionManager.InnerObject as SFConnectionManager.SFConnectionManager; if (this.ksConnectionManager == null) throw new Exception("Couldn't get the Salesforce connection manager, "); this.sfConnection = this.ksConnectionManager.AcquireConnection(transaction) as ForceClient; } } public override void ReleaseConnections() { if (ksConnectionManager != null) { this.ksConnectionManager.ReleaseConnection(sfConnection); } } public override void ReinitializeMetaData() { this.ComponentMetaData.RemoveInvalidInputColumns(); base.ReinitializeMetaData(); } public override DTSValidationStatus Validate() { return base.Validate(); } public override IDTSCustomProperty100 SetComponentProperty(string propertyName, object propertyValue) { if (propertyName == "SOAQ" && ComponentMetaData.OutputCollection[0].OutputColumnCollection.Count == 0) { AddOutputColumns(propertyValue.ToString()); } return base.SetComponentProperty(propertyName, propertyValue); } public override void ProvideComponentProperties() { // Reset the component. base.ProvideComponentProperties(); base.RemoveAllInputsOutputsAndCustomProperties(); ComponentMetaData.RuntimeConnectionCollection.RemoveAll(); IDTSCustomProperty100 sf_query = ComponentMetaData.CustomPropertyCollection.New(); sf_query.Name = "SOAQ"; sf_query.Description = "Salesforce Connector Query"; //Commenting query out as it will be provided manauuly and later entered in from form. sf_query.Value = sfQuery; IDTSOutput100 output = ComponentMetaData.OutputCollection.New(); output.Name = "SFOutput"; IDTSRuntimeConnection100 connection = ComponentMetaData.RuntimeConnectionCollection.New(); connection.Name = "K Salesforce"; } public override void PreExecute() { base.PreExecute(); IDTSOutput100 output = ComponentMetaData.OutputCollection[0]; mapOutputColsToBufferCols = new int[output.OutputColumnCollection.Count]; for (int i = 0; i < ComponentMetaData.OutputCollection[0].OutputColumnCollection.Count; i++) { // Here, "i" is the column count in the component's outputcolumncollection // and the value of mapOutputColsToBufferCols[i] is the index of the corresponding column in the // buffer. mapOutputColsToBufferCols[i] = BufferManager.FindColumnByLineageID(output.Buffer, output.OutputColumnCollection[i].LineageID); } } }
已尝试的解决方案
- 在Visual Studio中更改平台目标为Any CPU,也尝试过x86和x64
- 修改SSIS包的ProtectionLevel属性
- 将包级别的延迟验证属性设为True
- 设置
run64bitRuntime为False
环境:SQL Server 2019、Visual Studio 2019
内容的提问来源于stack exchange,提问作者Shaggy
相关产品推荐
相关产品推荐

