在 BizTalk 2004/2006 中利用 XLINQ 概念 +
编写简短的代码来解决您复杂的难题。
引言
在本文中,我提出了在 BizTalk 2004/2006 和未来版本中利用 XLINQ 概念的想法。 XLINQ 是 LINQ 的一部分,是对 C# 语言的增强。 请注意,在撰写本文时,LINQ 增强功能处于 CTP 阶段,因此我们不能将其视为概念验证。
什么是 XLINQ?
LINQ(语言集成查询)是一组 .NET Framework 语言扩展的代码名称。 这是一种通过构建像 SQL 这样的表达式来访问数据的巧妙方法。 DLINQ 是一组组件,可帮助在 SQL 和 LINQ 之间转换数据。
XLINQ 是一种简单轻量级的 XML API,旨在从内存和性能的角度简化 XML 的使用。
场景
在 2003 年,我使用 BizTalk 2004 将 Siebel CME 与我们客户端网络中的其他应用程序集成。 Siebel 公开 UAN(通用应用程序网络)层,用于与外部应用程序共享通用模式。 Siebel CME UAN 2.0 包提供了 12 个业务流程与其他系统集成,其中之一是 ProcessBilling
流程,用于更新订单,其中包含有关每个单独订购的行项目的信息。 源消息如下所示
<Orders>
<LineItem Code="101">
<User ID="UI023">
<Product> <OpCode>ADD</OpCode>
<Name>Product A</Name> <Qty> 1</Qty> </Product>
</User>
<User ID="UI023">
<Product> <OpCode>UPDATE</OpCode>
<Name>Product B</Name> </Product>
</User>
<User ID="UI024">
<Product> <OpCode>ADD</OpCode>
<Name>Product D</Name> </Product>
</User>
<User ID="UI024">
<Product> <OpCode>UPDATE</OpCode>
<Name>Product E</Name> </Product>
</User>
</LineItem >
<LineItem Code="102">
<User ID="UI023">
<Product> <OpCode>DELETE</OpCode>
<Name>Product C</Name> </Product>
</User>
<User ID="UI024">
<Product> <OpCode>UPDATE</OpCode>
<Name>Product D</Name> </Product>
</User>
<User ID="UI024">
<Product> <OpCode>ADD</OpCode>
<Name>Product F</Name> </Product>
</User>
</LineItem >
</Orders>
目标系统 Portal net 公开了每个用户的三个 Web 服务方法,例如“Add
”、“Modify
”和“cancel
”。 我们必须根据订单 ID、用户 ID 和 OpCode 对大型 XML 进行排序和分组,并调用 Infranet 来处理具有排序结果的订单。 我们尝试编写自定义 XSLT,但在聚合数据时遇到困难,这存在很大的性能问题。 然后我们选择了 .NET C# 帮助类,并编写了如下代码
private static XmlDocument GetListSortedByUser(XmlDocument document,
out int RecCount)
{
//Main arraylist to store the ordelines as it is from source
ArrayList arrOrderLineItemsList = new ArrayList();
// Get the order lines node list
XmlNodeList xmlunl = document.SelectNodes(xpathOrderLines,nsmgr);
ArrayList objUserOperationCodeList = new ArrayList();
// iterate for each order line and navigate through each order
// line and add the operation code, orderid, and user id to the
// arraylist Towards the end of this for each loop add it to
// the main array
foreach(XmlNode xmlNodeRdr in xmlunl)
{ ……………………………..
if (xmlNodeRdr.SelectSingleNode(xpathOrderId,nsmgr) != null)
{ ………………..
}
// Add Operation Code to the array arrUserOperationCodeList
if (xmlNodeRdr.SelectSingleNode(xpathOperationCode,
nsmgr) != null)
{
….
}
// Get the party node list
XmlNodeList xmlparty = xmlNodeRdr.SelectNodes(xpathParty,
nsmgr);
foreach(XmlNode xmlNodeParty in xmlparty)
{
if (xmlNodeParty.SelectSingleNode(xpathPartyRole,
nsmgr) != null)
{
……………….
}
}
// Separate Arraylist to hold the orderline values stored above based on the
// operation code
// Delete operation code arraylist
ArrayList arrDeleteList = new ArrayList();
// Add operation code arraylist
ArrayList arrAddList = new ArrayList();
// Update operation code arraylist
ArrayList arrUpdateList = new ArrayList();
// For loop to add each order line to its arraylist based on its
// operation code value
for(int i = 0; i lessthan objUserOperationCodeList.Count; i++)
{
object eachLineDetails;
eachLineDetails = objUserOperationCodeList[i];
ArrayList tempArrayList = new ArrayList();
tempArrayList = (ArrayList)eachLineDetails;
if(tempArrayList[1].ToString().Trim() == "Delete")
arrDeleteList.Add(objUserOperationCodeList[i]);
if(tempArrayList[1].ToString().Trim() == "Add")
arrAddList.Add(objUserOperationCodeList[i]);
if(tempArrayList[1].ToString().Trim() == "Update")
arrUpdateList.Add(objUserOperationCodeList[i]);
}
arrDeleteList = PerformSort(arrDeleteList);
// Call the method to perform sort on add arraylist
arrAddList = PerformSort(arrAddList);
// Call the method to perform sort on update arraylist
arrUpdateList = PerformSort(arrUpdateList);
objUserOperationCodeList.Clear();
// Add the sorted Delete arrayList to this new arraylist
for (int i=0; i lessthan arrDeleteList.Count;i++)
{
objUserOperationCodeList.Add(arrDeleteList[i]);
}
// Add the sorted Add arrayList to this new arraylist
for (int i=0; i lessthan arrAddList.Count;i++)
{
objUserOperationCodeList.Add(arrAddList[i]);
}
// Add the sorted Update arrayList to this new arraylist
for (int i=0; i lessthan arrUpdateList.Count;i++)
{
objUserOperationCodeList.Add(arrUpdateList[i]);
}
// the for loop to iterate through each order line and
// construct the xml back
// from the grouped and sorted values in arraylist
int iter=0;
// iterate through each order line node
foreach(XmlNode xmlNodeRdr in xmlunl)
{
document = new XmlDocument();
}
return document;
}
编写了将近 300 行 C# 帮助代码,仅用于排序和分组。
我们如何在 XLINQ 中实现相同的功能?
XElement OrdersGrp =
new XElement("Orders",
from user in orders.Descendants("User")
from userid in user.Attributes("ID")
group user by (string)userid into userGroup
let userid = userGroup.Key
select
new XElement("User",
new XAttribute("ID",
userid),
from user in userGroup
from opCode in user.Descendants("OpCode")
group user by (string)opCode into opCodeGroup
let opCode = opCodeGroup.Key
select
new XElement("Product",
new XElement("OpCode",
opCode),
opCodeGroup.Descendants("Name")
)));
只有一行? ??? (好吧,我用 ; 分号来计算行数)这是您期望的输出
<Orders>
<User ID="UI023">
<Product>
<OpCode>ADD</OpCode>
<Name>Product A</Name>
</Product>
<Product>
<OpCode>UPDATE</OpCode>
<Name>Product B</Name>
</Product>
<Product>
<OpCode>DELETE</OpCode>
<Name>Product C</Name>
</Product>
</User>
<User ID="UI024">
<Product>
<OpCode>ADD</OpCode>
<Name>Product D</Name>
<Name>Product F</Name>
</Product>
<Product>
<OpCode>UPDATE</OpCode>
<Name>Product E</Name>
<Name>Product D</Name>
</Product>
</User>
</Orders>
结论
XLINQ 开辟了一种新方法来简化您对 XML 的数据访问,从而使您能够开发非常高效的 Biztalk 接口。
可以对 Biztalk 消息进行排序和分组。 如果有人有兴趣,他们可以编写一个通用 functoid 用于在映射中对消息进行排序。
开始梦想您在 XLINQ 中的下一步,并告诉我您的更新... 干杯。
本文中的所有代码均已使用 Microsoft LINQ 项目 2006 年 5 月 CTP 编译。
历史
- 2006 年 7 月 29 日:首次发布