如何检索包并使用其可执行文件/组件附加到EzAPI中添加的组件?

时间:2013-11-20 12:23:21

标签: templates ssis ezapi

我有一个包含容器的包,从文件加载。我想用EzAPI将一个新组件附加到容器中 该组件随EzAPI一起添加,现在我只需要检索包中容器的名称即可附加它。

如何在EzAPI中检索containercomponent的名称?

        // Load template package.
        package.LoadFromFile("Package.dtsx");
        // I hoped with one of these for loops to retrieve the name of a component within the template package.
        foreach (var ezEx in package.Executables)
        {
        }
        foreach (var ezEx in package.EzExecs)
        {
        }
        // This component should be connected to a component of the template package.
        var truncateTableTask = new EzExecSqlTask(package)
        {
            Name = "EST Truncate Table",
            Connection = destConn,
            SqlStatementSource = " TRUNCATE TABLE " + destinationTableName
        };

1 个答案:

答案 0 :(得分:1)

虽然我等着回复您的代码的详细信息,但请随时查看我在EzAPI上的各种帖子。特别感兴趣的是,sequence containers and precedence constraints涵盖了所有这些。

归结为使用 AttachTo 方法 objA.AttachTo(objB)或者如果您需要使用优先约束,请使用添加方法到对象的PrecedenceConstraints集合,例如executableObject.PrecedenceConstraints.Add(objA, objB)

编辑0

鉴于您的示例代码和其中的注释,我认为您遇到的问题是,当SSIS包中有演示数据时,EzAPI会变得非常困惑。对象模型本身没有空间感知。如果我将数据流任务添加到包中,我没有指定在画布上绘制对象的位置。这是使用VS开发包的一个不幸的神器。为了使这个布局工作在幕后工作,VS序列化所有这些布局数据并将其写入SSIS包的节点。 *插入关于使用XML存储XML的方法。

因此,程序包运行时不需要布局数据,否则会严重污染EzAPI。然后,您的选项将使用EzAPI删除演示数据 forgo,并使用裸机(基本库)。

Josh Robinson的文章Editing Existing SSIS Package via EzAPI or Standard SSIS API Doesn’t Update Layout in BIDS涵盖了演示文稿的内容,这将使您的生活更轻松。

痛苦

我使用Biml生成了一个包含单个序列容器的样本包。不是必需的,但这可以让未来的读者跟随。

<!-- language: xml -->
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <!-- Change ConnectionString below. Privider if not 2012, Data Source for certain -->
        <OleDbConnection
            Name="destConn"
            ConnectionString="Data Source=localhost\dev2012;Initial Catalog=tempdb;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"
            />
    </Connections>
    <Packages>
        <Package
            Name="20095907_ezapi"
            ConstraintMode="Linear">
            <!--
            CREATE TABLE dbo.[20095907_ezapi]
            (
                MyColumn int NULL
            );
            -->
            <Connections>
                <Connection ConnectionName="destConn"/>
            </Connections>
            <Variables>
                <Variable Name="destinationTableName" DataType="String">dbo.[20095907_ezapi]</Variable>
            </Variables>
            <Tasks>
                <Container
                    Name="MyCleverContainer"
                    ConstraintMode="Linear"
                    >
                </Container>
            </Tasks>
        </Package>
    </Packages>
</Biml>

用一个包裹武装我然后花了我的午餐时间与对象模型混在一起。核心问题是你需要能够调用truncateTableTask.AttachTo(seq);,其中seq在Ez对象域中,或者你需要获得truncateTableTask的基本可执行版本来调用PrecedenceConstraints.Add(seq, truncateTableTaskBase)

以下是我不完整的愚蠢行为。现在发布它,以便您至少可以使用一些代码以及解释为什么事情就像它们一样。

    public static void soFix()
    {
        string sourceFile = @"C:\Users\bfellows\Documents\Visual Studio 2012\Projects\Demo\Demo\20095907_ezapi.dtsx";
        EzPackage package = null;
        EzOleDbConnectionManager destConn = null;
        string destinationTableName = "dbo.[20095907_ezapi]";

        package = new EzPackage();
        package.LoadFromFile(sourceFile);

        destConn = new EzOleDbConnectionManager(package, package.Connections["destConn"]);
        bool foundSomething = false;

        // This component should be connected to a component of the template package.
        var truncateTableTask = new EzExecSqlTask(package)
        {
            Name = "EST Truncate Table",
            Connection = destConn,
            SqlStatementSource = " TRUNCATE TABLE " + destinationTableName
        };


        Executable fromObject = null;
        Executable toObject = null;

        // I hoped with one of these for loops to retrieve the name of a component within the template package.
        foreach (Executable item in package.Executables)
        {
            // http://technet.microsoft.com/en-us/library/microsoft.sqlserver.dts.runtime.eventsprovider.aspx
            // This enumerates items using the base object types
            // They will either be a TaskHost or a container type
            //      Microsoft.SqlServer.Dts.Runtime.ForEachLoop
            //      Microsoft.SqlServer.Dts.Runtime.ForLoop
            //      Microsoft.SqlServer.Dts.Runtime.Sequence                

            TaskHost outer = item as TaskHost;
            TaskHost inner = item as TaskHost;

            Sequence seq = item as Sequence;
            ForLoop fl = item as ForLoop;
            ForEachLoop fel = item as ForEachLoop;

            if (seq != null)
            {
                Console.WriteLine(string.Format("{0} : {1}", seq.GetType(), seq.Name));
                toObject = item;
            }

            if (fl != null)
            {
                Console.WriteLine(string.Format("{0} : {1}", fl.GetType(), fl.Name));

            }
            if (fel != null)
            {
                Console.WriteLine(string.Format("{0} : {1}", fel.GetType(), fel.Name));

            }

            // Task examples
            // Here is where you would test the executable's type to determine if it's what you're looking for
            if (inner != null)
            {
                if (inner.InnerObject is Microsoft.SqlServer.Dts.Pipeline.Wrapper.MainPipe)
                {
                    Console.WriteLine("I haz DFT");
                }

                if (inner.InnerObject is Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ExecuteSQLTask)
                {
                    Executable exec = item;
                    if (outer.ID == truncateTableTask.ID)
                    {
                        Console.WriteLine("We are looking at the object we just created");
                        fromObject = item;
                    }
                    ExecuteSQLTask tmp = (ExecuteSQLTask)inner.InnerObject;
                    Console.WriteLine("I haz execute SQL Task");
                }


            }

        }

        // package.EzExecs.Count showing 0?
        // The layout XML does not play nicely with EzAPI
        // http://joshrobi.blogspot.com/2012/04/editing-existing-ssis-package-via-ezapi.html
        foreach (var ezEx in package.EzExecs)
        {
            // this enumerates items using the EZ object types
            Console.WriteLine(ezEx);
            Console.WriteLine(ezEx.EzName);
        }

        // Attach my execute sql task as a preceding executable
        // However, since we're in classic object land, ezapi won't help
        Package classic = new Package();
        classic.LoadFromXML(package.SaveToXML(), null);

        try
        {
            PrecedenceConstraint pc = null;
            pc = classic.PrecedenceConstraints.Add(fromObject as Executable, toObject as Executable);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            Console.WriteLine(ex.InnerException);
            throw;
        }

        Application app = new Application();
        app.SaveToXml(sourceFile, classic, null);

    }