步骤 4(可选):定义关联
关联链接业务线 (LOB) 系统中的相关实体。例如,客户与 AdventureWorks 系统中的销售订单相关联,因为客户生成销售订单。客户与销售订单之间存在一对多的关系。关联包含指向父实体和子实体的指针以及指向某个业务逻辑的指针,此业务逻辑允许客户端从父实体获取子实体。遍历关联只是 LOB 系统上的方法调用。关联使您可以更轻松地创建大纲-细节应用程序。有关业务数据目录中的关联的详细信息,请参阅关联。
本主题介绍如何在 AdventureWorks2000 数据库中定义客户与销售订单之间的关联。查找特定客户的销售订单是常见的业务需要。通过在业务数据目录中定义此关联,您可以在给定客户 ID 的情况下找到销售订单。定义关联是一个两步过程。首先,在 Customer 实体中定义在已给定客户 ID 时将返回销售订单的方法。其次,通过指定在 Customer 实体中定义的方法,定义两个实体(即 Customer 和 SalesOrder)之间的关联。
备注
这是一个源实体、一个目标实体的简单示例。如果您具有多个源实体而只有一个目标实体,您可能希望在目标实体中定义关联逻辑。然而,业务数据目录允许您在同一个 LobSystem 实例的任何实体中定义关联逻辑。
先决条件
步骤 2:定义实体、方法和筛选器,如果需要,则执行步骤 3(可选):定义操作
定义关联
在步骤 2 或步骤 3 中打开 AdventureWorks2000.xml 文件。
在 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 >= @MinSalesOrderID) AND (SalesOrderID <= @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 >= @MinIndividualID) AND (IndividualID <= @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>
在 <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>
保存 XML 文件。
在再次添加应用程序定义之前,必须从业务数据目录中删除您在步骤 1 中创建的 AdventureWorksSample 应用程序。要删除 AdventureWorksSample,请按照下列步骤操作:
打开“SharePoint 3.0 管理中心”。
在左侧导航窗格中,单击您的“共享服务提供程序 (SSP)”的名称。
在“业务数据目录”部分,单击“查看应用程序”以查看已注册的应用程序。
单击 AdventureWorksSample 以打开“查看应用程序:AdventureWorksSample”页。
最后,单击“应用程序设置”部分中的“删除应用程序”。
现在,将应用程序定义添加到业务数据目录中。有关详细信息,请参阅如何:将应用程序定义添加到业务数据目录。
通过创建一个业务数据列表和一个关联 Web 部件来测试元数据。有关详细信息,请参阅如何:测试业务数据关联。
Next Steps
步骤 5(可选):定义 IDEnumerator 方法和启用业务数据搜索
See Also
任务
AdventureWorks SQL Server 2000 示例