by Sandro Pereira | Dec 17, 2019 | BizTalk Community Blogs via Syndication
The BizTalk Pipeline Components Extensions Utility Pack community project for BizTalk Server 2016, once again, got a new update! It now has a new component that you can use in your custom BizTalk Server pipelines: SQL Server Polling Debatch Message By Grouping Filter Pipeline Component.
Debatching messages, which are received from WCF-SQL Adapter, is quite a simple task to do. You need to:
- Specify that the message has an envelope by setting the Envelope property to Yes

- Specify the Body XPath property

- And finally, set the Max Occurs property to 1

Next, the default XMLReceive pipeline will do the rest. However, what happens if you want to extend and customize this behavior? In my case, let’s imagine I have the following row samples:
SeqId
|
Name
|
MsgIdentifier
|
Role
|
Company
|
1
|
Sandro Pereira
|
0000001
|
Team Lead
|
DevScope
|
2
|
Pedro Almeida
|
0000001
|
Senior Developer
|
DevScope
|
3
|
Rui Romano
|
0000002
|
Team Lead
|
DevScope
|
4
|
João Sousa
|
0000003
|
Team Lead
|
DevScope
|
5
|
Joana Barbosa
|
0000002
|
BI Architect
|
DevScope
|
We will poll all the data from the SQL Database (not all, but let’s say the first 20 lines), and we want to split or debatch the incoming message based on the value of the MsgIdentifier property. So, after passing the receive pipeline, we will get, based on the previous example, 3 different messages:

The main question is: How do we handle scenarios where debatching is done based on business logic?
The answer is that we don’t have anything out-of-the-box that allows us to do these kinds of tasks. Most of you will think about debatching these kinds of messages inside an orchestration.
However, the best way for us to achieve this goal is to develop a custom Disassemble pipeline component.
SQL Server Polling Debatch Message By Grouping Filter Pipeline Component
The reason for choosing the Disassemble stage is simple; it is here that normally the process of breaking up a large interchange message into smaller messages happens, by removing the Envelopes, which is often called “debatching”. So, this should indeed be the place for us to create our custom Disassemble pipeline component.
The SQL Server Polling Debatch Message By Grouping Filter pipeline component is a custom disassemble pipeline component that can be used to debatch incoming messages from the WCF-SQL adapter, by filtering from a specific element of the message. It will provide the following capabilities:
- It allows you to define the grouping element
- This will be an integer that will define the position of the element inside the message after the source code

Note: This custom pipeline component can be used with other LOB adapters but it was never tested before.
public void Disassemble(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
string originalDataString;
try
{
//fetch original message
Stream originalMessageStream = inmsg.BodyPart.GetOriginalDataStream();
byte[] bufferOriginalMessage = new byte[originalMessageStream.Length];
originalMessageStream.Read(bufferOriginalMessage, 0, Convert.ToInt32(originalMessageStream.Length));
originalDataString = System.Text.ASCIIEncoding.ASCII.GetString(bufferOriginalMessage);
}
catch (Exception ex)
{
throw new ApplicationException("Error in reading original message: " + ex.Message);
}
XmlDocument originalMessageDoc = new XmlDocument();
StringBuilder messageString;
string msgBatchId = string.Empty;
try
{
//load original message
originalMessageDoc.LoadXml(originalDataString);
//fetch namespace and root element
string namespaceURI = originalMessageDoc.DocumentElement.NamespaceURI;
string rootElement = originalMessageDoc.DocumentElement.Name;
//start batching messages
messageString = new StringBuilder();
messageString.Append("<" + rootElement + " xmlns:ns0='" + namespaceURI + "'>");
string rowId = string.Empty;
foreach (XmlNode childNode in originalMessageDoc.DocumentElement.ChildNodes)
{
messageString.Append("<" + childNode.Name + ">");
foreach (XmlNode rows in childNode.ChildNodes)
{
rowId = rows.ChildNodes[this.GroupingElement].InnerText;
if (msgBatchId == string.Empty)
msgBatchId = rowId;
if (msgBatchId != rowId)
{
messageString.Append("</" + childNode.Name + ">");
messageString.Append("</" + rootElement + ">");
//Queue message
CreateOutgoingMessage(pc, messageString.ToString(), namespaceURI, rootElement);
msgBatchId = rowId;
messageString.Remove(0, messageString.Length);
messageString.Append("<" + rootElement + " xmlns:ns0='" + namespaceURI + "'>");
messageString.Append("<" + childNode.Name + ">");
messageString.Append(rows.OuterXml);
}
else
{
messageString.Append(rows.OuterXml);
}
}
messageString.Append("</" + childNode.Name + ">");
}
messageString.Append("</" + rootElement + ">");
CreateOutgoingMessage(pc, messageString.ToString(), namespaceURI, rootElement);
}
catch (Exception ex)
{
throw new ApplicationException("Error in writing outgoing messages: " + ex.Message);
}
finally
{
messageString = null;
originalMessageDoc = null;
}
// _msgs.Enqueue(inmsg);
}
The source code shown here is just a snippet. To be able to use this, you can download the latest version from the BizTalk Pipeline Components Extensions Utility Pack.
What is BizTalk Pipeline Components Extensions Utility Pack?
The BizTalk Pipeline Components Extensions Utility Pack is a set of custom pipeline components (libraries) with several custom pipeline components that can be used in receive and send pipelines, which will provide an extension of BizTalk out-of-the-box pipeline capabilities.

The project is available on the BizTalk Server Open Source Community repository on GitHub (https://github.com/BizTalkCommunity). Everybody can contribute with new pipeline components that can be used to extend or improve the existing BizTalk Server capabilities.
At the moment, it is only available for BizTalk Server 2016, but it will soon be compiled and available for previous versions of the product.
Where to download it?
You can download BizTalk Pipeline Components Extensions Utility Pack from GitHub here: BizTalk Pipeline Components Extensions Utility Pack.
The post BizTalk Pipeline Components Extensions Utility Pack: SQL Server Polling Debatch Message By Grouping Filter Pipeline Component appeared first on BizTalk360.
by stephen-w-thomas | Aug 8, 2006 | Stephen's BizTalk and Integration Blog
This was a question (paraphrased) on the BizTalkGurus.com Forum: “How can I take email attachments and put them as is into a folder?”
When using the POP3 Receive Adapter, you have the ability to receive multiple items as attachments and the adapter will handle them using MIME processing. You do not need a custom pipeline.
When receiving a multi-attachment message, you have the ability to define one of the parts as the main message Body. If you leave the default (0), the email message body will be the main message Body and all attachments will be additional parts to the message.
Lets say you have 3 attachments and you want to receive in an email and write them out to disk in a folder location (you can always publish them to the message box and do anything you want with the messages). You could probably use a custom pipeline to break out the multi-part message into separate messages…
I found a very simple and straight forward approach to accomplish this task. The Orchestration looks like this:
The key is to create an Orchestration variable of type Microsoft.XLANGs.BaseTypes.XLANGMessage. In order to do this, you need to add a reference to Microsoft.XLang.BaseTypes.dll. Once you have this variable, you just need to set it equal to your input message like: oXMessage = In.
You now have access to everything the XLangMessage has available; most importantly Count and access to all the message parts. Now a simple loop can be used to loop over the parts and create new output messages for each message part.
The output messages are created like: Out = oXMessage[n] were n is the message part index (starting at 1 since 0 is the Body). It’s that simple. It’s a total of 4 lines of code inside the Expression Shape and Message Construct.
I have a sample solution available for download below.
Download: Splitting POP3 Email Attachments in BizTalk Server 2006
See the readme.txt file for set up information.
by stephen-w-thomas | Apr 3, 2006 | Stephen's BizTalk and Integration Blog
In a past edition of The BizTalker, I talked about how easy it is to use custom XSLT inside the BizTalk Mapper to sort data. Sorting data inside the map can be doing using inline XSLT like this:
<xsl:for-each select=”Record”>
<xsl:sort select=”Id” data-type=”number” order=”ascending”/>
<xsl:element name=”Customers”>
<xsl:element name=”Id”><xsl:value-of select=”Id” /></xsl:element>
</xsl:element>
</xsl:for-each>
Sometimes sorting just is not enough. What if you also needed to group your data and break it up into single messages? This can be done several different ways including using xpath, .net components, or something external to BizTalk all together; with none of them really being ideal.
Another non-ideal way to accomplish grouping and debatching is to use pure BizTalk Messaging! Yes, pure messaging can group and debatch your data. Now, it is a little strange and takes a few hops through the message box, but it is a relatively simple solution to implement in a short amount of time.
So, how does it work?
Pass 1 will apply a map on the Receive Port to sort the data. The Send Port will apply another map to group the data.
The grouping map using two Functoids. One determines if the current record and the past record have the same Id. The second does the grouping.
The code in these Scripting Functoids looks like this:
True / False
string newNode = “”;
string pastValue = “X”;
public string MakeNewNode(string currentValue)
{
if (pastValue != currentValue)
{
pastValue = currentValue;
newNode = “true”;
}
else
newNode = “false”;
return newNode;
}
Grouping
<xsl:template name=”GroupByID”>
<xsl:param name=”param1″/>
<xsl:param name=”param2″/>
<xsl:if test=”$param1=’true'”>
<xsl:element name=”Group”>
<xsl:for-each select=”//Customers[Id=$param2]”>
<xsl:element name=”Customer”>
<xsl:element name=”Id”><xsl:value-of select=”Id”/></xsl:element>
<xsl:element name=”Name”><xsl:value-of select=”Name”/></xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:template>
Pass 2 will apply an envelope to split the data inside the Receive Port and publish single messages to the message box.
Download the Sorting, Grouping, & Debatching Sample Code.
See the ReadMe.txt for set up information. Also note that I needed two projects for this solution. That is because the envelope schema needs to be in a separate project due to the way pipelines read the schema collections.
by stephen-w-thomas | Feb 28, 2006 | Downloads
Debatching can be done several different ways in BizTalk 2004. With a few message box hops, debatching can be done with a few maps and an envelope schema in pure messaging. This sample shows a map for Sorting, a map for Grouping, and the Envelope for debatching.
This sample will work in BizTalk 2004 and BizTalk 2006.
Get more information from the original blog post on this topic: https://www.biztalkgurus.com/biztalk_server/biztalk_blogs/b/biztalk/archive/2006/04/03/how-to-use-biztalk-messaging-for-grouping_2c00_-sorting_2c00_-and-debatching.aspx
by stephen-w-thomas | Dec 1, 2005 | Downloads
In some business scenarios you may be required to receive a batch file that must be broken up and processed as single messages by BizTalk Server 2004. This could allow for individual record level processing, selective content based routing, or single message mapping.
Get more information from the original blog post on this topic: https://www.biztalkgurus.com/biztalk_server/biztalk_blogs/b/biztalk/archive/2004/12/13/debatching-options-and-performance-in-biztalk-server-2004.aspx
by stephen-w-thomas | Jul 12, 2005 | Stephen's BizTalk and Integration Blog
Envelopes can be used with the Xml Disassembler in Biztalk 2004 to break up larger Xml messages into single messages. Another approach to message debatching is to use xpath in a loop inside an Orchestration. Both these approaches are covered in this Message Debatching Options Lab for Biztalk 2004.
This lab will take around 40 minutes to complete and is based on Microsoft’s hands-on-labs.
Download: Message Debatching Options Hands-on Lab
Setup is simple. Unzip the download to your c:\ drive. Make sure the root folder named “Microsoft Hands-On-Labs” is located at c:\. The lab manual is located under \ILL009_Debatching. The exercises are located in the \Source\Exercises folder. The full sample solution is located in the \Source\Solution folder.
This lab is recommended for beginner and above biztalk users looking to learn more about message debatching in biztalk.
by stephen-w-thomas | Mar 30, 2005 | Downloads
The flat file disassembler can produce single record output or a single batch output. This sample shows how to accomplish each task when you need it. Make sure to read the blog content below for additional information.
This sample should work with BizTalk 2004 and BizTalk 2006.
Get more information from the original blog post on this topic: https://www.biztalkgurus.com/biztalk_server/biztalk_blogs/b/biztalk/archive/2004/12/17/flat-file-disassembler-output-types-in-biztalk-server-2004.aspx
by stephen-w-thomas | Mar 21, 2005 | Stephen's BizTalk and Integration Blog
It is a common request. How can I debatch a message into smaller batches rather than single messages inside BizTalk 2004?
I have tried many times to get this accomplished natively inside the pipeline. One would think it would be as easy as setting the group property to 10 if you wanted a batch size of 10, but that does not seem to work. The only way I have been able to break up a message into smaller batches has been inside custom code.
I wrote a .net component that can be called using an atomic scope shape from inside an Orchestration. This component will return smaller batches of any size you specify inside the Orchestration and wrap the smaller batches inside a specified root node. This .net component uses the XmlTextReader to stream the message along and debatch it.
This .net component is called StreamHelper. It illustrates the following:
- Using XmlTextReader
- Passing an Xlang Message into a .net component
- Returning an Xlang Message from a .net component
- Setting context properties on a message returned from a .net component
Download: Debatch Streaming Sample
Setup: Download and extract the solution. Build and GAC the StreamHelper assembly then Build and Deploy the DebatchProperties and DebatchOrch assemblies. I have included a basic sample file to test with. For more detailed information on the sample see the comments throughout the solution.
A better way to do it?
I’m sure there is. I just put this together in a short amount of time. I would guess the most efficient place for this type of work would be inside a custom pipeline component. But, working with custom pipelines can be difficult.
How does this debatching approach perform compared to the others?
Performance was almost identical to that of the Xml Node List inside an atomic scope. In this sample, I used the XmlTextReader and passed Xlang messages in and out of the component to try to increase performance. That did not seem to accomplish anything. As expected, as the total number of messages inside the atomic scope increased the performance decreased.
Type |
XML Size (MB) |
# Nodes |
Batch Size |
Time (Sec) |
Msg/Sec |
Msg Size (kb) |
.net Stream |
1.6 |
500 |
1 |
5 |
100.0 |
3.0 |
.net Stream |
3.6 |
1100 |
1 |
18 |
61.1 |
3.0 |
.net Stream |
7.2 |
2200 |
1 |
44 |
50.0 |
3.0 |
.net Stream |
18.1 |
5500 |
1 |
224 |
24.6 |
3.0 |
.net Stream |
128.6 |
38500 |
1 |
— |
FAIL |
— |
.net Stream |
1.6 |
500 |
10 |
1 |
500.0 |
3.0 |
.net Stream |
3.6 |
1100 |
10 |
3 |
366.7 |
3.0 |
.net Stream |
7.2 |
2200 |
10 |
9 |
244.4 |
3.0 |
.net Stream |
18.1 |
5500 |
10 |
15 |
366.7 |
3.0 |
.net Stream |
128.6 |
38500 |
10 |
159 |
242.1 |
3.0 |
For more debatching information please see my past post:
Debatching Options and Performance Considerations in BizTalk 2004
by stephen-w-thomas | Mar 21, 2005 | Downloads
Debatching into single messages is easy with BizTalk 2004. This sample shows how messages can be groups into batches of any size inside an Orchestration using an external .net component. The external .net component uses streams to read the message from an Orchestration. The message is passed into the component as an XLang message type.
This sample should work in BizTalk 2004 and BizTalk 2006.
Get more information from the original blog post on this topic: https://www.biztalkgurus.com/biztalk_server/biztalk_blogs/b/biztalk/archive/2005/03/22/debatching-messages-into-smaller-batches-in-an-orchestration.aspx
by stephen-w-thomas | Dec 12, 2004 | Stephen's BizTalk and Integration Blog
Download This Article and Sample Code Here: Debatching Options and Performance Considerations in BizTalk 2004 White Paper and Sample Code
Related Sample: Xml Envelope Debatching
In some business scenarios you may be required to receive a batch file that must be broken up and processed as single messages by BizTalk Server 2004. This could allow for individual record level processing, selective content based routing, or single message mapping.
General Debatching Design Considerations
Here are some general design considerations you might want to think about when planning a debatching approach with BizTalk Server 2004.
General Debatching Design Considerations
- Header and Trailer Validation Requirements for Flat Files
- All or Nothing Debatching
- Should single records be allowed to fail some type of validation, mapping, or routing
- Mapping Required
- As a whole message
- As single messages
- Last Message Indicator Required
- Is another process depending on knowing when the last message finished
- Ordered Message Processing
- Time of Day Processing
- Will this affect other processes running
- File Size (less important than in past versions of BizTalk)
- Record Volume
Although this article is focused on general debatching options, I want to go into more detail on some of the design considerations above.
Header and Trailer Validation
Typically batch files are received in a format other than XML, such as flat file. In this case, the file will typically have a Header and Trailer record. These records typically contain information about the number of records in the file, date, time, etc. In some business processes this information needs to be validated prior to processing the file. This creates some interesting design challenges.
Some options for this type of validation include a pre-debatching map, validation of the file using .net, or validation inside an Orchestration. The best option depends on message size since some batch files can be very large (I consider very large as greater than half a gigabyte as XML).
Last Message Indicator Required
Debatching implies breaking up a file into many different pieces. Sometimes, the single items must still behave as a batch. Some business processes require knowing when the last message in the batch has been processed to activate another process. In addition, sometimes ordered processing of the debatching messages is required.
Ordered Message Processing
Ordered processing of the messages can be accomplished in a few ways. One way is to use an ordered delivery supported adapter, like MSMQt. This would require the debatcher to write the messages in the correct order to the queue for processing. This may also require the use of a convoy to route all the single messages to the same business process. The challenge is to allow for ordered delivery without significantly affecting performance.
BizTalk 2004 Debatching Options
BizTalk 2004 provides us with several different methods for batch file debatching. What is the best way to split up your files? As always, that depends on your exact business scenario.
In this posting, I will look at four different debatching options, review the performance data, and explain the benefits of each type. I also have the test Orchestrations I used available for download. I do not provide any sample files, but you can make your own since the Orchestrations use untyped messages. Just make your structure like: DataData.
The four methods I will cover are:
- Receive Port Pipeline Debatching
- Orchestration XPath Debatching
- Orchestration Atomic Scope Node List Debatching
- Orchestration Outside .Net Component Debatching
Debatching Options Performance Test Results
Here are the results of the performance tests on each type of debatching. Tests were run on a 2.4 GHz desktop with 1.25GB RAM. The sample file produced single records that were 3 KB each. No mapping was done on the files and times do not include time to send the files using a Send Port. This is just the time to run the pipeline or orchestrations. Throughput is intended to show a general idea of the amount of data running through the process; it is not the overall system throughput. Additional tests were run for XPath and Node List that produced larger output files of 29.9 KB and 299.0 KB.
Type |
XML Size (MB) |
# Msg |
Time (Sec) |
Msg/Sec |
Msg Size (KB) |
Throughput (KB/sec) |
Receive Port |
1.6 |
500 |
8 |
62.5 |
3.0 |
205 |
Receive Port |
3.6 |
1100 |
14 |
78.6 |
3.0 |
263 |
Receive Port |
7.2 |
2200 |
34 |
64.7 |
3.0 |
217 |
Receive Port |
18.1 |
5500 |
59 |
93.2 |
3.0 |
314 |
Receive Port |
128.6 |
38500 |
603 |
63.8 |
3.0 |
218 |
XPath |
1.6 |
500 |
121 |
4.1 |
3.0 |
14 |
XPath |
3.6 |
1100 |
200 |
5.5 |
3.0 |
18 |
XPath |
7.2 |
2200 |
667 |
3.3 |
3.0 |
11 |
XPath |
18.1 |
5500 |
3077 |
1.8 |
3.0 |
6 |
Node List |
1.6 |
500 |
9 |
55.6 |
3.0 |
182 |
Node List |
3.6 |
1100 |
21 |
52.4 |
3.0 |
176 |
Node List |
7.2 |
2200 |
30 |
73.3 |
3.0 |
246 |
Node List |
18.1 |
5500 |
225 |
24.4 |
3.0 |
82 |
Node List |
54.3 |
16500 |
1460 |
11.3 |
3.0 |
38 |
Node List |
128.6 |
38500 |
15256 |
2.5 |
3.0 |
9 |
.Net Call |
1.6 |
500 |
49 |
10.2 |
3.0 |
33 |
.Net Call |
3.6 |
1100 |
220 |
5.0 |
3.0 |
17 |
.Net Call |
7.2 |
2200 |
663 |
3.3 |
3.0 |
11 |
.Net Call |
18.1 |
5500 |
3428 |
1.6 |
3.0 |
5 |
.Net Call |
54.3 |
16500 |
27000 |
0.6 |
3.0 |
2 |
Type |
XML Size (MB) |
# Msg |
Time (Sec) |
Msg/Sec |
Msg Size (KB) |
Throughput (KB/sec) |
XPath |
12 |
400 |
232 |
1.7 |
29.9 |
53 |
XPath |
35.9 |
1200 |
870 |
1.4 |
29.9 |
42 |
Node List |
12 |
400 |
10 |
40.0 |
29.9 |
1229 |
Node List |
35.9 |
1200 |
28 |
42.9 |
29.9 |
1313 |
Node List |
107.7 |
3600 |
128 |
28.1 |
29.9 |
862 |
Type |
XML Size (MB) |
# Msg |
Time (Sec) |
Msg/Sec |
Msg Size (KB) |
Throughput (KB/sec) |
XPath |
14.9 |
50 |
40 |
1.3 |
299.0 |
381 |
XPath |
59.6 |
200 |
430 |
0.5 |
299.0 |
142 |
XPath |
119.2 |
400 |
1849 |
0.2 |
299.0 |
66 |
Node List |
14.9 |
50 |
8 |
6.3 |
299.0 |
1907 |
Node List |
59.6 |
200 |
27 |
7.4 |
299.0 |
2260 |
Node List |
119.2 |
400 |
126 |
3.2 |
299.0 |
969 |
Debatching Options Detailed Overview
Receive Port Pipeline Debatching – A.K.A. Envelope Processing
This type of debatching requires defining an envelope as the basic structure of your message. This is handled a little differently depending on if your input is XML or Flat File. For native XML messages, you must define a Body node that will be broken out by the pipeline component. When receiving Flat Files, life is easier since you have control over the final schema structure to be broken out.
Using this type of debatching, it will not be possible to determine when all of the large messages have been sent or processed without considerable effort (i.e. like using a convoy that will degrade performance).
For more information and a sample of this type of debatching please see my past post on this topic.
Pros: Fast! Fast! Fast! I am guessing this is because it is all streaming and uses “streaming XPath”. Great for messaging only solutions that require content based routing of single messages.
Cons: All or nothing debatching in the pipeline. Your XML schema must have a top level node for the envelope to strip out the single messages under it. Since the message is not persisted to the database until after the pipeline and map, if something fails in the pipeline or map the entire message will be lost. In addition, I always have a hard time getting envelopes to work correctly. I think that is just user error on my part.
Mapping: Maps are applied to the single messages. If one fails, the whole batch is failed. This limits your flexibility.
Orchestration XPath Debatching – (Best Bet!)
This is my favorite type of debatching. This method of debatching comes from Darren Jefford’s Blog. I like it the best because it provides the most control over the process. I know exactly when the last message has finished. This would be useful if you are using this type of debatching to make a .net call or web service submission for each debatched message inside the loop. Just remember this will lower the performance and you will be running sequentially.
I was shocked at the relatively poor performance of this debatching. When I was testing smaller files, under 100 single messages, I was getting 10+ messages per second.
Even with the slower performance at higher output message sizes, this is still my preferred method of debatching when message size permits. Simple reasons: control and manageability!
Just be careful, I ran a 128 MB file through this and after 1 hour I only had 1500 message out. I think the slower performance is from the XPath call itself inside the loop. I think it is rescanning the whole message each time I run the loop.
Pros: Excellent flexibility inside the Orchestration. Great control of the processing of your document! This process is sequential and ordered by default. Ability to loop over anything you can XPath and can easily (this is always a relative term) build mini-batches if needed. This is something Receive Pipelines are not able to do without extensive custom code.
Cons: Performance degrades quickly as message size increases. Downright slow on large messages and a resource hog. In some cases, the sequential and ordered processing of this type of debatching may be limiting to the process.
Mapping: Complete flexibility. Map before the loop on the whole message or inside the loop as single messages. Inside the loop, single items can fail mapping and if handled correctly will not stop document processing.
Orchestration Atomic Scope Node List Debatching
This is conceptually a combination of the XPath and Receive Port Debatching. You have the flexibility to loop around anything you can XPath but your process is all or nothing. This must be done inside an Atomic Scope shape since Node List is not serializable.
This type of debatching seems to be more sensitive to output message size rather than input message size. That would make sense, since the smaller the message the more messages the Atomic Transaction will be building up.
To accomplish this debatching, I set up a Node List and an Enumerator inside the Orchestration. Then, I use MoveNext inside a loop to extract out the single message for the current node. This involved casting the object to a Node and getting the value using OuterText. For complete details, see the samples provided.
Pros: Fast! In some cases, the Atomic Scope may be beneficial.
Cons: All or nothing debatching since you must use an Atomic Scope shape. Massive resource hog! My CPU was maxed at 100% the entire time the process was running. In addition, this seems to tax SQL Server. After running some processes it needed to be restarted or the computer just would not do anything.
In one test, the process ran for over 8 hours maxing out the CPU the whole time just to have something fail and it all roll back.
Mapping: Map before the loop on the whole message or inside the loop as single messages.
Orchestration Outside .Net Component Debatching
This debatching uses an outside .net component to break up the message. The thought here is that the message will not be scanned for each loop. As the performance numbers show, using an outside .net component did not increase performance.
Inside the Orchestration, I created a new instance of a helper class and passed in the input XML message. Then, I looped over the document using a Node List. I returned items based on an index I passed in from a loop shape inside an Orchestration. The performance of this is nearly identical to the XPath method.
Are there any better ways to do it? I looked into using XmlNodeReader inside the .net component but I did not try to get it to work.
Pros: None. I would not recommend this approach.
Cons: Slow. This adds an additional component to maintain outside of BizTalk.
Mapping: Mapping can be done on the whole message or on single messages.
Conclusion
BizTalk Server 2004 offers a variety of options for breaking up large files for processing. An evaluation of your exact business requirements will help you decide on the option that is best for you.
I welcome questions, comments, feedback, and other ways to debatch large messages! Just drop me an email.