我有一个包含容器的包,从文件加载。我想用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
};
答案 0 :(得分:1)
虽然我等着回复您的代码的详细信息,但请随时查看我在EzAPI上的各种帖子。特别感兴趣的是,sequence containers and precedence constraints涵盖了所有这些。
归结为使用 AttachTo 方法
objA.AttachTo(objB)
或者如果您需要使用优先约束,请使用添加方法到对象的PrecedenceConstraints集合,例如executableObject.PrecedenceConstraints.Add(objA, objB)
鉴于您的示例代码和其中的注释,我认为您遇到的问题是,当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);
}