当我在等待有关您的代码的详细信息时,请随时查看我在 EzAPI 上发布的各种帖子。特别有趣的是,序列容器和优先约束涵盖了所有这些。
它归结为使用AttachTo方法,
objA.AttachTo(objB)
或者如果您需要摆弄优先约束,请使用Add方法到对象的 PrecedenceConstraints 集合,例如executableObject.PrecedenceConstraints.Add(objA, objB)
编辑 0
鉴于您的示例代码和其中的注释,我认为您遇到的问题是,当 SSIS 包中有演示数据时,EzAPI 会变得非常混乱。对象模型本身没有空间意识。如果我将数据流任务添加到包中,我不会指定对象应在画布上绘制的位置。这是使用 VS 开发包的不幸产物。为了使这些布局工作,VS 在幕后序列化所有这些布局数据并将其写入 SSIS 包的一个节点。*插入关于使用 XML 存储 XML 的 yo dawg meme。
因此,运行包不需要布局数据,否则会真正破坏 EzAPI。然后,您的选择变成了剥离演示数据或放弃使用 EzAPI,只使用裸机(基础库)。
Josh Robinson 的文章Editing Existing SSIS Package via EzAPI or Standard SSIS API Don't Update Layout in BIDS and will make your life easier, Josh Robinson 的文章介绍了剥离演示文稿的内容。
到痛苦
我使用 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);
}