You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 05:40:56