我有一个情况,我的主biml生成150执行包任务.我需要生成序列容器,以便每个容器(150/10)15执行包主任务包中的序列容器任务.
您能否帮我找到合适的解决方案任何想法/欢迎工作exmaples /代码库!
<Tasks>
<# foreach (var package in RootNode.Packages) { #>
<ExecutePackage Name="Execute <#=package.Name#>" >
<ExternalProjectPackage Package="<#=package.PackageFileName#>" />
</ExecutePackage>
<# } #>
</Tasks>
Run Code Online (Sandbox Code Playgroud)
这个答案将利用Biml的一些高级概念.第一个是分层,所以我们将在第1层生成150个包.然后在第2层(或任何大于上一层的数字),我们将能够将第0层的人工成果引用到(最大层数 - 1).
第0层是静态/平坦Biml(在本例中我们没有任何内容).由于我们将循环生成子包,它将自动在第1层,但我选择明确这里,以防你有前驱但动态的任务要解决
<#* .... #> 是一个超级强大的注释构造,被Biml编译器忽略
<#+ .... #> 是用于在Biml中添加显式方法和类的构造
我们还将使用Extension方法将我们的包大致分成组,然后填充到Sequence Containers中.
此代码生成空白SSIS包,其名称范围从so_54773502_000到so_54773502_149(总共150个)
<#@ template tier="1" #>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Packages>
<#foreach (int index in Enumerable.Range(0, 150)){#>
<Package Name="so_54773502_<#= string.Format("{0:000}", index) #>" />
<#}#>
</Packages>
</Biml>
Run Code Online (Sandbox Code Playgroud)
在这里,我们指定我们想要多少个并行容器.该Split方法的结果是列表列表.对于外部容器列表中的每个元素,我们需要添加一个Sequence Container.对于该弹出列表中的每个元素,我们需要枚举它并执行包任务.
<#@ template tier="2" #>
<#
int taskCountPerContainer = 10;
int currentContainerNumber = 0;
#>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Packages>
<Package Name="master">
<Tasks>
<#*
This is such a fun bit of LINQ. I used the Split extension so handily defined on the linked question
I pass in a List of package names and how many buckets I want and it returns a list of lists
From there, we enumerate through the list bucket and for each element we find, we create a sequence
container. Then, for each element in the bucket, we add an Execute Package Task.
I was unable to Split an instance of AstPackageNodes as it resulted in the error below but the only reason
your sample needed the full object was to provide both Name and PackageFileName properties. We can derive
the second given the first
// foreach(var outerlist in Split(this.RootNode.Packages.ToList<AstPackageNode>(),taskCountPerContainer)){
// results in this error.
// Destination array was not long enough. Check destIndex and length, and the array's lower bounds.
// TODO: Check with Varigence or run in C# project
*#>
<#foreach(var listOfPackages in Split(this.RootNode.Packages.Select(x => x.Name).ToList<string>(), taskCountPerContainer)){#>
<Container Name="SEQC_<#=currentContainerNumber++#>" ConstraintMode="Linear">
<Tasks>
<#foreach(var packageName in listOfPackages){#>
<ExecutePackage Name="EPT <#=packageName#>"><ExternalProjectPackage Package="<#=packageName#>.dtsx"/></ExecutePackage>
<#}#>
</Tasks>
</Container>
<#}#>
</Tasks>
</Package>
</Packages>
</Biml>
<#+
// https://stackoverflow.com/questions/419019/split-list-into-sublists-with-linq
public static IList<List<T>> Split<T>(IList<T> source, int buckets)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / buckets)
.Select(x => x.Select(v => v.Value).ToList())
.ToList();
}
#>
Run Code Online (Sandbox Code Playgroud)
看吧,很多包被执行了!