Skip to main content

Bulk Changes to Tasks in BimlExpress

Why Patch Properties After the Fact

Default values can be set up front using variables in include files or C# / VB code files, but that only helps if every place that creates the object reaches for the same helper. When the same Biml project has several different ways to create a Dataflow Task and they all need to share a property such as DefaultBufferMaxRows, retrofitting every constructor is painful. BimlStudio handles this with transformers; BimlExpress does not have transformers, but the AllDefinedSuccessors method on the object model produces a similar effect.

The Pattern

A single high tier file walks every package and reaches every Dataflow Task descendant via AllDefinedSuccessors. The file sets DefaultBufferMaxRows on each one. Because the tier is high, every package defined elsewhere in the project has already been emitted by the time this file runs.

VB version:

<#@ template tier="999" language="VB" optionexplicit="False" #>
<#
for each df in RootNode.Packages.SelectMany(
Function(c) c.AllDefinedSuccessors().OfType(of AstDataflowTaskNode)())
df.DefaultBufferMaxRows = 20000
next
#>

C# version:

<#@ template tier="999" #>
<#
foreach (var df in RootNode.Packages.SelectMany(
c => c.AllDefinedSuccessors().OfType<AstDataflowTaskNode>()))
{
df.DefaultBufferMaxRows = 20000;
}
#>

The tier needs to be high enough that every package this script is meant to touch has already been defined when this file runs. A safe default is well above any tier already in use; the example uses 999.

Generalizing the Approach

The same trick works for any AST node. To touch a different node type, change the OfType filter. To set a different property, replace the DefaultBufferMaxRows assignment. To add a child object such as a precedence constraint or a logging task, call the relevant Add method on the discovered node. The constraint is the same: only objects that exist by the time the high tier file runs are reachable.