步骤 4(可选):定义关联

关联链接业务线 (LOB) 系统中的相关实体。例如,客户与 AdventureWorks 系统中的销售订单相关联,因为客户生成销售订单。客户与销售订单之间存在一对多的关系。关联包含指向父实体和子实体的指针以及指向某个业务逻辑的指针,此业务逻辑允许客户端从父实体获取子实体。遍历关联只是 LOB 系统上的方法调用。关联使您可以更轻松地创建大纲-细节应用程序。有关业务数据目录中的关联的详细信息,请参阅关联

本主题介绍如何在 AdventureWorks2000 数据库中定义客户与销售订单之间的关联。查找特定客户的销售订单是常见的业务需要。通过在业务数据目录中定义此关联,您可以在给定客户 ID 的情况下找到销售订单。定义关联是一个两步过程。首先,在 Customer 实体中定义在已给定客户 ID 时将返回销售订单的方法。其次,通过指定在 Customer 实体中定义的方法,定义两个实体(即 Customer 和 SalesOrder)之间的关联。

备注

这是一个源实体、一个目标实体的简单示例。如果您具有多个源实体而只有一个目标实体,您可能希望在目标实体中定义关联逻辑。然而,业务数据目录允许您在同一个 LobSystem 实例的任何实体中定义关联逻辑。

先决条件

步骤 2:定义实体、方法和筛选器,如果需要,则执行步骤 3(可选):定义操作

定义关联

  1. 在步骤 2 或步骤 3 中打开 AdventureWorks2000.xml 文件。

  2. 在 Product 实体定义之后的 <Entities> 标记内添加下面的 XML。此 XML 定义 SalesOrder 和 Customer 实体。请注意,Customer 实体还包含称为 GetSalesOrdersForCustomer() 的方法的定义,此方法在给定客户 ID 的情况下返回销售订单。这是关联方法。

    <Entity EstimatedInstanceCount="10000" Name="SalesOrder">
          <LocalizedDisplayNames>
            <LocalizedDisplayName LCID="1033">Sales Order</LocalizedDisplayName>
          </LocalizedDisplayNames>
          <Identifiers>
            <Identifier Name="SalesOrderID" TypeName="System.Int32" />
          </Identifiers>
          <Methods>
            <Method Name="GetSalesOrders">
              <Properties>
                <Property Name="RdbCommandText" Type="System.String">
                  SELECT SalesOrderID, OrderDate, SubTotal, IndividualID
                  FROM SalesOrderHeader, Individual WHERE (SalesOrderID &gt;= @MinSalesOrderID)
                  AND (SalesOrderID &lt;= @MaxSalesOrderID) AND (SalesOrderNumber LIKE @SalesOrderNumber)
                  AND SalesOrderHeader.CustomerID = Individual.CustomerID
                </Property>
                <Property Name="RdbCommandType" Type="System.String">Text</Property>
              </Properties>
              <FilterDescriptors>
                <FilterDescriptor Type="Comparison" Name="ID" >
                  <Properties>
                    <Property Name="Comparator" Type="System.String">Equals</Property>
                  </Properties>
                </FilterDescriptor>
                <FilterDescriptor Type="Wildcard" Name="SalesOrderNumber" />
              </FilterDescriptors>
              <Parameters>
                <Parameter Direction="In"  Name="@MinSalesOrderID">
                  <TypeDescriptor TypeName="System.Int32" IdentifierName="SalesOrderID" 
                                  AssociatedFilter="ID" Name="MinSalesOrderID">
                    <DefaultValues>
                      <DefaultValue MethodInstanceName="SalesOrderFinderInstance" Type="System.Int32">0</DefaultValue>
                    </DefaultValues>
                  </TypeDescriptor>
                </Parameter>
                <Parameter Direction="In"  Name="@MaxSalesOrderID">
                  <TypeDescriptor TypeName="System.Int32" IdentifierName="SalesOrderID" AssociatedFilter="ID" Name="MaxSalesOrderID">
                    <DefaultValues>
                      <DefaultValue MethodInstanceName="SalesOrderFinderInstance" Type="System.Int32">99999999</DefaultValue>
                    </DefaultValues>
                  </TypeDescriptor>
                </Parameter>
                <Parameter Direction="In"  Name="@SalesOrderNumber">
                  <TypeDescriptor TypeName="System.String" AssociatedFilter="SalesOrderNumber" Name="SalesOrderNumber">
                    <DefaultValues>
                      <DefaultValue MethodInstanceName="SalesOrderFinderInstance" Type="System.String">%</DefaultValue>
                      <DefaultValue MethodInstanceName="SalesOrderSpecificFinderInstance" Type="System.String">%</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">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">ID</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                          </TypeDescriptor>
                          <TypeDescriptor TypeName="System.DateTime" Name="OrderDate">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">Order Date</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                            <Properties>
                              <Property Name="DisplayByDefault" Type="System.Boolean">true</Property>
                            </Properties>
                          </TypeDescriptor>
                          <TypeDescriptor TypeName="System.Int32" Name="IndividualID">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">IndividualID</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                            <Properties>
                              <Property Name="DisplayByDefault" Type="System.Boolean">true</Property>
                            </Properties>
                          </TypeDescriptor>
                          <TypeDescriptor TypeName="System.Decimal" Name="SubTotal">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">SubTotal</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                            <Properties>
                              <Property Name="DisplayByDefault" Type="System.Boolean">true</Property>
                            </Properties>
                          </TypeDescriptor>
                        </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>
        <Entity EstimatedInstanceCount="10000" Name="Customer">
          <Properties>
            <Property Name="Title" Type="System.String">FirstName</Property>
          </Properties>
          <Identifiers>
            <Identifier Name="IndividualID" TypeName="System.Int32" />
          </Identifiers>
          <Methods>
            <Method Name="GetCustomers">
              <Properties>
                <Property Name="RdbCommandText" Type="System.String">SELECT * FROM Individual WHERE (IndividualID &gt;= @MinIndividualID) AND (IndividualID &lt;= @MaxIndividualID) AND ((FirstName+' '+LastName) LIKE @Name)</Property>
                <Property Name="RdbCommandType" Type="System.String">Text</Property>
              </Properties>
              <FilterDescriptors>
                <FilterDescriptor Type="Comparison" Name="ID" >
                  <Properties>
                    <Property Name="Comparator" Type="System.String">Equals</Property>
                  </Properties>
                </FilterDescriptor>
                <FilterDescriptor Type="Wildcard" Name="Name" />
              </FilterDescriptors>
              <Parameters>
                <Parameter Direction="In"  Name="@MinIndividualID">
                  <TypeDescriptor TypeName="System.Int32" IdentifierName="IndividualID" AssociatedFilter="ID" Name="MinIndividualID">
                    <DefaultValues>
                      <DefaultValue MethodInstanceName="CustomerFinderInstance" Type="System.Int32">0</DefaultValue>
                    </DefaultValues>
                  </TypeDescriptor>
                </Parameter>
                <Parameter Direction="In"  Name="@MaxIndividualID">
                  <TypeDescriptor TypeName="System.Int32" IdentifierName="IndividualID" AssociatedFilter="ID" Name="MaxIndividualID">
                    <DefaultValues>
                      <DefaultValue MethodInstanceName="CustomerFinderInstance" Type="System.Int32">99999999</DefaultValue>
                    </DefaultValues>
                  </TypeDescriptor>
                </Parameter>
                <Parameter Direction="In"  Name="@Name">
                  <TypeDescriptor TypeName="System.String" AssociatedFilter="Name" Name="Name">
                    <DefaultValues>
                      <DefaultValue MethodInstanceName="CustomerFinderInstance" Type="System.String">%</DefaultValue>
                      <DefaultValue MethodInstanceName="CustomerSpecificFinderInstance" Type="System.String">%</DefaultValue>
                    </DefaultValues>
                  </TypeDescriptor>
                </Parameter>
                <Parameter Direction="Return"  Name="Customers">
                  <TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="CustomerDataReader">
                    <TypeDescriptors>
                      <TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="CustomerDataRecord">
                        <TypeDescriptors>
                          <TypeDescriptor TypeName="System.Int32" IdentifierName="IndividualID" Name="IndividualID">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">ID</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                          </TypeDescriptor>
                          <TypeDescriptor TypeName="System.String" Name="FirstName">
                            <Properties>
                              <Property Name="DisplayByDefault" Type="System.Boolean">true</Property>
                            </Properties>
                          </TypeDescriptor>
                          <TypeDescriptor TypeName="System.String" Name="LastName">
                            <Properties>
                              <Property Name="DisplayByDefault" Type="System.Boolean">true</Property>
                            </Properties>
                          </TypeDescriptor>
                        </TypeDescriptors>
                      </TypeDescriptor>
                    </TypeDescriptors>
                  </TypeDescriptor>
                </Parameter>
              </Parameters>
              <MethodInstances>
                <MethodInstance Name="CustomerFinderInstance" Type="Finder" ReturnParameterName="Customers" />
                <MethodInstance Name="CustomerSpecificFinderInstance" Type="SpecificFinder" ReturnParameterName="Customers" />
              </MethodInstances>
            </Method>
            <Method Name="GetSalesOrdersForCustomer">
              <Properties>
                <Property Name="RdbCommandText" Type="System.String">SELECT SalesOrderID, OrderDate, SubTotal,Individual.IndividualID FROM SalesOrderHeader,Individual WHERE SalesOrderHeader.CustomerID=Individual.CustomerID and Individual.IndividualID=@IndividualID</Property>
                <Property Name="RdbCommandType" Type="System.String">Text</Property>
              </Properties>
              <Parameters>
                <Parameter Direction="In"  Name="@IndividualID">
                  <TypeDescriptor TypeName="System.Int32" IdentifierName="IndividualID" Name="IndividualID" />
                </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" IdentifierEntityName="SalesOrder" IdentifierName="SalesOrderID" Name="SalesOrderID">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">ID</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                          </TypeDescriptor>
                          <TypeDescriptor TypeName="System.DateTime" Name="OrderDate">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">Order Date</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                            <Properties>
                              <Property Name="DisplayByDefault" Type="System.Boolean">true</Property>
                            </Properties>
                          </TypeDescriptor>
                          <TypeDescriptor TypeName="System.Int32" Name="IndividualID">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">IndividualID</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                            <Properties>
                              <Property Name="DisplayByDefault" Type="System.Boolean">true</Property>
                            </Properties>
                          </TypeDescriptor>
                          <TypeDescriptor TypeName="System.Decimal" Name="SubTotal">
                            <LocalizedDisplayNames>
                              <LocalizedDisplayName LCID="1033">SubTotal</LocalizedDisplayName>
                            </LocalizedDisplayNames>
                            <Properties>
                              <Property Name="DisplayByDefault" Type="System.Boolean">true</Property>
                            </Properties>
                          </TypeDescriptor>
                        </TypeDescriptors>
                      </TypeDescriptor>
                    </TypeDescriptors>
                  </TypeDescriptor>
                </Parameter>
              </Parameters>
            </Method>
          </Methods>
          <Actions>
            <Action Name="Send Email" Position="1" IsOpenedInNewWindow="true" Url="mailto:{0}.msn.com" ImageUrl="">
              <ActionParameters>
                <ActionParameter Name="FirstName" Index="0" />
              </ActionParameters>
            </Action>
          </Actions>
        </Entity>
    
  3. 在 <Entities> 标记之后添加下面的 XML,以定义 Customer 与 SalesOrder 实体之间的关联:

      <Associations>
        <Association AssociationMethodEntityName="Customer" AssociationMethodName="GetSalesOrdersForCustomer" AssociationMethodReturnParameterName="SalesOrders" Name="CustomerToSalesOrder" IsCached="true">
          <!-- Associations are just subclasses of MethodInstances. 
          They can also take ReturnTypeDescriptorName optionally. For 
          details, see SampleWebServiceMetadata.-->
          <SourceEntity Name="Customer" />
          <DestinationEntity Name="SalesOrder" />
          <!-- The source and destination entities can be the same. 
          For more information, see the SampleWebService example.-->
        </Association>
      </Associations>
    
  4. 保存 XML 文件。

  5. 在再次添加应用程序定义之前,必须从业务数据目录中删除您在步骤 1 中创建的 AdventureWorksSample 应用程序。要删除 AdventureWorksSample,请按照下列步骤操作:

    1. 打开“SharePoint 3.0 管理中心”。

    2. 在左侧导航窗格中,单击您的“共享服务提供程序 (SSP)”的名称。

    3. 在“业务数据目录”部分,单击“查看应用程序”以查看已注册的应用程序。

    4. 单击 AdventureWorksSample 以打开“查看应用程序:AdventureWorksSample”页。

    5. 最后,单击“应用程序设置”部分中的“删除应用程序”。

  6. 现在,将应用程序定义添加到业务数据目录中。有关详细信息,请参阅如何:将应用程序定义添加到业务数据目录

  7. 通过创建一个业务数据列表和一个关联 Web 部件来测试元数据。有关详细信息,请参阅如何:测试业务数据关联

Next Steps

步骤 5(可选):定义 IDEnumerator 方法和启用业务数据搜索

See Also

任务

AdventureWorks SQL Server 2000 示例

概念

业务数据目录:元数据模型