MSDN Visual系列:利用关联来过滤MOSS中的BDC数据

本文介绍如何在Microsoft Office SharePoint Server (MOSS)中使用业务数据连接器(BDC)定义实体及其实现主子行为的方法。文章详细讲解了如何通过定义关联方法来过滤BDC数据,并通过业务数据WebPart实现主子实体之间的关联。

 原文:http://msdn2.microsoft.com/en-us/library/bb410047.aspx

BDC允许我们为特定的LOB(line-of-business)系统定义多个实体。而且,在元数据文件中,我们可以创建关联来定义实体间的层次关系。如,有两个实体的定义,customers和orders。我们可以创建关联将customer实体直接与order实体联系在一起。这样就可以允许用户在MOSS中创建并使用主子(master-child)行为。

本文将向大家介绍如何在MOSS中利用关联来过滤BDC数据。大家继续使用之前在介绍BDC实体创建的文章中使用的元数据文件。

  1. 在元数据文件中添加Sales Order实体

    在已有的Customer实体元素下面添加下列内容。该XML定义了一个新的实体,名为SalesOrder。
    < Entity  Name ="SalesOrder" >
       
    < Properties >
          
    < Property  Name ="Title"  Type ="System.String" > salesordernumber </ Property >
       
    </ Properties >
       
    < Identifiers >
          
    < Identifier  Name ="SalesOrderID"  TypeName ="System.Int32" />
       
    </ Identifiers >
       
    < Methods >
          
    < Method  Name ="GetSalesOrders" >
             
    < Properties >
                
    < Property  Name ="RdbCommandText"  Type ="System.String" >
                   SELECT
                      soh.salesorderid,
                      soh.orderdate,
                      soh.shipdate,
                      soh.status,
                      soh.salesordernumber,
                      soh.customerid
                   FROM
                      sales.salesorderheader soh
                      inner join sales.customer c
                      on soh.customerid = c.customerid
                   WHERE
                      c.customertype = 'i'
                      AND (soh.salesorderid 
    &gt;  @minSalesOrderID AND 
                           soh.salesorderid 
    &lt;  @maxSalesOrderID)
                
    </ Property >
                
    < Property  Name ="RdbCommandType"  Type ="System.String" > Text </ Property >
             
    </ Properties >
             
    < Parameters >
                
    < Parameter  Direction ="In"  Name ="@minSalesOrderID" >
                      
    < TypeDescriptor  TypeName ="System.Int32"  Name ="SalesOrderID"  
                      IdentifierName
    ="SalesOrderID" >
                      
    < DefaultValues >
                         
    < DefaultValue  MethodInstanceName =
                         "SalesOrderFinderInstance"
     Type ="System.Int32" > 0
                         
    </ DefaultValue >
                         
    < DefaultValue  MethodInstanceName =
                         "SalesOrderSpecificFinderInstance"
     Type ="System.Int32" > 0
                         
    </ DefaultValue >
                      
    </ DefaultValues >
                   
    </ TypeDescriptor >
                
    </ Parameter >
                
    < Parameter  Direction ="In"  Name ="@maxSalesOrderID" >
                   
    < TypeDescriptor  TypeName ="System.Int32"  Name ="SalesOrderID"  
                   IdentifierName
    ="SalesOrderID" >
                      
    < DefaultValues >
                         
    < DefaultValue  MethodInstanceName =
                         "SalesOrderFinderInstance"
     Type ="System.Int32" >
                         9999999
    </ DefaultValue >
                         
    < DefaultValue  MethodInstanceName =
                         "SalesOrderSpecificFinderInstance"
     Type ="System.Int32" >
                         9999999
    </ DefaultValue >
                      
    </ DefaultValues >
                   
    </ TypeDescriptor >
                
    </ Parameter >
                
    < Parameter  Direction ="Return"  Name ="SalesOrders" >
                   
    < TypeDescriptor  TypeName ="System.Data.IDataReader, System.Data, 
                   Version=2.0.3600.0, Culture=neutral, PublicKeyToken=
                   b77a5c561934e089"
     IsCollection ="true"  Name ="SalesOrderDataReader" >
                      
    < TypeDescriptors >
                         
    < TypeDescriptor  TypeName ="System.Data.IDataRecord, System.Data, 
                         Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
     
                         Name
    ="SalesOrderDataRecord" >
                            
    < TypeDescriptors >
                               
    < TypeDescriptor  TypeName ="System.Int32"  IdentifierName =
                               "SalesOrderID"
     Name ="SalesOrderID"   />
                               
    < TypeDescriptor  TypeName ="System.DateTime"   Name ="orderdate"   />
                               
    < TypeDescriptor  TypeName ="System.DateTime"  Name ="shipdate"   />
                               
    < TypeDescriptor  TypeName ="System.String"  Name ="status"   />
                               
    < TypeDescriptor  TypeName ="System.String"  Name ="salesordernumber"   />
                               
    < TypeDescriptor  TypeName ="System.Int32"  Name ="customerid"   />
                               
    </ TypeDescriptors >
                         
    </ TypeDescriptor >
                      
    </ TypeDescriptors >
                   
    </ TypeDescriptor >
                
    </ Parameter >
             
    </ Parameters >
             
    < MethodInstances >
                
    < MethodInstance  Name ="SalesOrderFinderInstance"  Type ="Finder"  
                ReturnParameterName
    ="SalesOrders"   />
                
    < MethodInstance  Name ="SalesOrderSpecificFinderInstance"  Type ="SpecificFinder"  
                ReturnParameterName
    ="SalesOrders"   />
             
    </ MethodInstances >
          
    </ Method >
       
    </ Methods >
    </ Entity >
  2. 添加一个新的方法,基于CustomerID来过滤Orders

    SalesOrder实体中,已有的方法下面,添加一个新的方法,名为GetSalesOrdersForCustomer.。该方法包含了一个简单的SQL语句。特别值得注意的是WHERE语句,在这里通过customerID字段来进行过滤操作。另外,注意customerID的输入参数(@customerID),这里没有默认参数。该方法作为一个关联方法只有在用户选择了某个customer时才会被调用。

    注:输入参数有一个IdentifierName属性和一个IdentifierEntityName属性与其关联。尽管这里我们在SalesOrder实体中使用customerID,但事实上customerID是Customer实体的标识符。BDC使用customer的标识符来获取选定的customer所对应的特定的sales orders。
    < Method  Name ="GetSalesOrdersForCustomer" >
       
    < Properties >
          
    < Property  Name ="RdbCommandText"  Type ="System.String" >
             SELECT
             soh.salesorderid,
             soh.orderdate,
             soh.shipdate,
             soh.status,
             soh.salesordernumber
             FROM
             sales.salesorderheader soh
             inner join sales.customer c
             on soh.customerid = c.customerid
             where
             c.customertype = 'i'
             AND c.customerid = @customerID
          
    </ Property >
          
    < Property  Name ="RdbCommandType"  Type ="System.String" > Text </ Property >
       
    </ Properties >
       
    < Parameters >
          
    < Parameter  Direction ="In"  Name ="@customerID" >
             
    < TypeDescriptor  TypeName ="System.Int32"  Name ="CustomerID"  IdentifierEntityName =
             "Customer"
     IdentifierName ="CustomerID" >
                
    <!--  Note that we don't have any default values for this.  -->
                
    <!-- Also, note the IdentifierEntityName attribute referes to the customer entity. -->
             
    </ TypeDescriptor >
          
    </ Parameter >
          
    < Parameter  Direction ="Return"  Name ="SalesOrders" >
             
    < TypeDescriptor  TypeName ="System.Data.IDataReader, System.Data, 
             Version=2.0.3600.0, Culture=neutral, PublicKeyToken=
             b77a5c561934e089"
     IsCollection ="true"  Name ="SalesOrderDataReader" >
                
    < TypeDescriptors >
                   
    < TypeDescriptor  TypeName ="System.Data.IDataRecord, System.Data, 
                   Version=2.0.3600.0, Culture=neutral, PublicKeyToken=
                   b77a5c561934e089"
     Name ="SalesOrderDataRecord" >
                      
    < TypeDescriptors >
                         
    < TypeDescriptor  TypeName ="System.Int32"  IdentifierName =
                         "SalesOrderID"
     Name ="SalesOrderID"   />
                         
    < TypeDescriptor  TypeName ="System.DateTime"   Name ="orderdate"   />
                         
    < TypeDescriptor  TypeName ="System.DateTime"  Name ="shipdate"   />
                         
    < TypeDescriptor  TypeName ="System.String"  Name ="status"   />
                         
    < TypeDescriptor  TypeName ="System.String"  Name ="salesordernumber"   />
                      
    </ TypeDescriptors >
                   
    </ TypeDescriptor >
                
    </ TypeDescriptors >
             
    </ TypeDescriptor >
          
    </ Parameter >
       
    </ Parameters >
    </ Method >
  3. 在SalesOrder实体和Customer实体间定义关联

    添加下面的XML到LobSystem元素的结尾(在结束标记</Entities>后)。GetSalesOrdersForCustomer方法作为AssociationMethodName,SalesOrder实体作为AssociationMethodEntityName。同样的,SalesOrders参数被指定为返回参数。最后,源实体(SourceEntity,就是驱动关系的实体)和目标实体(DestinationEntity)元素在其中也分别进行了定义。

    关联方法可以在任何实体中存在(甚至是源实体和目标实体以外的实体)。唯一的一个要求是包含关联方法的实体必须写在其引用的其他实体的下面。比如本例中的SalesOrder实体必须放在Customer实体下面,因为在其中存在customer标识的引用。
    < Associations >
       
    < Association 
          
    AssociationMethodEntityName ="SalesOrder"
          AssociationMethodName
    ="GetSalesOrdersForCustomer"
          AssociationMethodReturnParameterName
    ="SalesOrders"
          AssociationMethodReturnTypeDescriptorName
    ="SalesOrderDataReader"
          Name
    ="CustomerToSalesOrders"   >
       
          
    < SourceEntity  Name ="Customer"   />
          
    < DestinationEntity  Name ="SalesOrder"   />
       
    </ Association >
    </ Associations >
  4. 增加LOBSystem根元素的版本号

    MOSS会阻止我们上传一个版本号小于或等于当前所承载的版本的元数据文件。因此,如果我们使用前面章节中创建的元数据文件,这里必须要提高其版本号。
  5. 保存并上传修改完成的元数据文件到BDC共享服务

    保存文件。打开管理中心,点左侧导航栏中的共享服务(通常名为SharedServices1)。在BDC一节中,点导入应用程序定义。点浏览,找到刚刚修改完成的元数据文件,双击。其他的应用程序定义项都用默认值就好,点导入。
  6.   使用业务数据WebPart来实现基于Customer的Orders筛选

    1.      在我们的站点首页中添加一个“业务数据列表”WebPart和一个“与业务数据相关的列表”WebPart。
    2.      在业务数据列表WebPart上,点“打开工具窗格”。
    3.      在工具窗格中的类型输入框中,输入 Customer 并回车。SharePoint Server 2007会将输入的内容解析为Customer (CRMDB)实体。
    4.      点确定后,customer实体就会显示在WebPart中了。
    5.      在与业务数据相关的列表WebPart中,点“打开工具窗格”。
    6.      在工具窗格中的类型输入框中,输入 SalesOrder并回车。注意到我们之前在关联中定义的CustomerToSalesOrders关系会自动出现在关系下拉列表中并选中。
    7.      点应用。
    8.      点SalesOrder列表WebPart的编辑菜单,点连接。点选获取相关项来源,然后选择Customer列表。
    9.      这样,在Customer列表WebPart中点一个customer就可以查看相关的sales orders了。

你准备好进行第三方协助了吗?

关联没必要只停留在一层上。本节将描述如何添加一个LineItem实体,并与sales order相关联。

注:该实体非常简单。它没有实现任何方法。因此,它不会显示在搜索中也不存在一个业务数据操作,或用在关联性过滤中。它最主要的也是唯一的目的就是显示一个与SalesOrder有关系的实体。

  1. 创建一个ListItem实体

    添加下面的XML内容到SalesOrder实体下面。正如之前提到的,这里实体间的顺序很重要。这个实体必须放在SalesOrder 实体下面,因为它的特定方法包含到SalesOrder 标识的引用。
    < Entity  Name ="LineItem" >
       
    < Properties >
          
    < Property  Name ="Title"  Type ="System.String" > Name </ Property >
       
    </ Properties >
       
    < Identifiers >
          
    < Identifier  Name ="LineItemID"  TypeName ="System.Int32" />
       
    </ Identifiers >
       
    < Methods >
          
    < Method  Name ="GetLineItemsForSalesOrder" >
             
    < Properties >
                
    < Property  Name ="RdbCommandText"  Type ="System.String" >
                   SELECT
                      sod.SalesOrderDetailID,
                      p.Name,
                      p.ProductNumber,
                      sod.CarrierTrackingNumber,
                      sod.OrderQty,
                      sod.UnitPrice,
                      sod.LineTotal
                   FROM
                      Sales.SalesOrderDetail sod
                      INNER JOIN Production.Product p
                      on sod.ProductID = p.ProductID
                   WHERE
                      sod.SalesOrderID = @salesorderID
                
    </ Property >
                
    < Property  Name ="RdbCommandType"  Type ="System.String" > Text </ Property >
             
    </ Properties >
             
    < Parameters >
                
    < Parameter  Direction ="In"  Name ="@salesorderID" >
                   
    < TypeDescriptor  TypeName ="System.Int32"  Name ="salesorderID"  
                      IdentifierEntityName
    ="SalesOrder"  
                      IdentifierName
    ="SalesOrderID" >
                   
    <!--  Note that we don't have any default values for this.  -->
                   
    </ TypeDescriptor >
                
    </ Parameter >
                
    < Parameter  Direction ="Return"  Name ="LineItems" >
                   
    < TypeDescriptor  TypeName ="System.Data.IDataReader, System.Data, 
                   Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
     
                         IsCollection
    ="true"  Name ="LineItemDataReader" >
                      
    < TypeDescriptors >
                         
    < TypeDescriptor  TypeName ="System.Data.IDataRecord, System.Data, 
                         Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
     
                            Name
    ="LineItemDataRecord" >
                            
    < TypeDescriptors >
                               
    < TypeDescriptor  TypeName ="System.Int32"  
                                  IdentifierName
    ="LineItemID"  
                                  Name
    ="SalesOrderDetailID"   />
                               
    < TypeDescriptor  TypeName ="System.String"  
                                  Name
    ="Name"   />
                               
    < TypeDescriptor  TypeName ="System.Int32"  
                                  Name
    ="CarrierTrackingNumber"   />
                               
    < TypeDescriptor  TypeName ="System.Int16"  
                                  Name
    ="OrderQty"   />
                               
    < TypeDescriptor  TypeName ="System.String"  
                                  Name
    ="UnitPrice"   />
                               
    < TypeDescriptor  TypeName ="System.String"  
                                  Name
    ="LineTotal"   />
                            
    </ TypeDescriptors >
                         
    </ TypeDescriptor >
                      
    </ TypeDescriptors >
                   
    </ TypeDescriptor >
                
    </ Parameter >
             
    </ Parameters >
             
    <!--  Note that we have no finder or specific finder.  
                This is because we don't need the line item to show up 
                in anything other than a Related List Web Part. 
    -->
          
    </ Method >
       
    </ Methods >
    </ Entity >

  2. 添加Sales Order到List Item的关联

    将SalesOrderToLineItems关联直接放在已有的关联下面。
        < Association 
          
    Name ="SalesOrderToLineItems"
          AssociationMethodEntityName
    ="LineItem"  
          AssociationMethodName
    ="GetLineItemsForSalesOrder"  
          AssociationMethodReturnParameterName
    ="LineItems"  
          AssociationMethodReturnTypeDescriptorName
    ="LineItemDataReader"  
          IsCached
    ="true" >
          
    < SourceEntity  Name ="SalesOrder"   />
          
    < DestinationEntity  Name ="LineItem"   />
       
    </ Association >

  3. 上传元数据文件并添加一个与业务数据相关的列表WebPart

    增加元数据文件的版本号并上传。最后,添加一个新的与业务数据相关的列表WebPart到我们的站点页面。这次,选择ListItem实体和GetLineItemsForSalesOrder关联。

小结:
BDC不仅可以显示LOB数据到门户中,还可以通过BDC关联来定义门户中的实体对LOB中其他实体内容的反应。业务数据关联允许我们使用业务数据列表WebPart来驱动与业务数据相关的列表WebPart ,从而实现主子行为。
其中需要我们掌握的要点有:

* 定义关联方法的实体必须放在所有与其有关的其他实体下面。
* 关联方法必须具备输入参数来映射所有源实体的标识。
* 关联方法的返回参数必须包含目标实体的标识。

查看视频

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值