Associations

Hi, I'm using the AdventureWorks BDC example to try to assiociate two entities. The example works, but when I do my modifications, I get the error "Could not find fields to insert all the Identifier Values to correctly execute an Association method." It's possible I've stared myself blind on this xml, but I am not able to find where the missing tags should go.

This is my bdc app def:

< xml version="1.0" encoding="utf-8" standalone="yes" >
<
LobSystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog BDCMetadata.xsd"
Type="Database"
Version="1.0.0.8" Name="MyLob"
xmlns="http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog">
<
Properties>
<
Property Name="WildcardCharacter" Type="System.String">%</Property>
</
Properties>
<
LobSystemInstances>
<
LobSystemInstance Name="MyLobInstance">
<
Properties>
<
Property Name="AuthenticationMode" Type="System.String">PassThrough</Property>
<
Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property>
<
Property Name="RdbConnection Data Source" Type="System.String">MyServer</Property>
<
Property Name="RdbConnection Initial Catalog" Type="System.String">MyDatabase</Property>
<
Property Name="RdbConnection Integrated Security" Type="System.String">SSPI</Property>
<
Property Name="RdbConnection Pooling" Type="System.String">false</Property>
</
Properties>
</
LobSystemInstance>
</
LobSystemInstances>
<
Entities>
<
Entity EstimatedInstanceCount="10000" Name="CreditLimit">
<
Identifiers>
<
Identifier Name="PolicyID" TypeName="System.Int32" />
<
Identifier Name="ActorID" TypeName="System.Int32" />
</
Identifiers>
<
Methods>
<Method Name="GetCreditLimits">
<
Properties>
<
Property Name="RdbCommandText" Type="System.String">
select PolicyID, ActorID, BuyerID, BuyerName from dbo.v_CreditLimits where (PolicyID = @PolicyID)
</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="BuyerName" />
</
FilterDescriptors>
<
Parameters>
<
Parameter Direction="In" Name="@PolicyID">
<
TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" AssociatedFilter="ID" Name="PolicyID">
<
DefaultValues>
<
DefaultValue MethodInstanceName="CreditLimitFinderInstance" Type="System.Int32">0</DefaultValue>
</DefaultValues>
</
TypeDescriptor>
</
Parameter>
<
Parameter Direction="Return" Name="CreditLimits">
<
TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="CreditLimitsDataReader">
<
TypeDescriptors>
<
TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, ublicKeyToken=b77a5c561934e089" Name="CreditLimitsDataRecord">
<
TypeDescriptors>
<
TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" Name="PolicyID"/>
<
TypeDescriptor TypeName="System.Int32" Name="ActorID"/>
<TypeDescriptor TypeName="System.Int32" Name="BuyerID"/>
<
TypeDescriptor TypeName="System.String" Name="BuyerName"/>
</
TypeDescriptors>
</
TypeDescriptor>
</TypeDescriptors>
</
TypeDescriptor>
</
Parameter>
</
Parameters>
<
MethodInstances>
<
MethodInstance Name="CreditLimitFinderInstance" Type="Finder" ReturnParameterName="CreditLimits" />
<
MethodInstance Name="CreditLimitSpecificFinderInstance" Type="SpecificFinder" ReturnParameterName="CreditLimits" />
</
MethodInstances>
</Method>
</
Methods>
</
Entity>
<
Entity EstimatedInstanceCount="10000" Name="Policy">
<
Properties>
<
Property Name="Title" Type="System.String">PolicyID</Property>
</
Properties>
<
Identifiers>
<
Identifier Name="PolicyID" TypeName="System.Int32" />
<
Identifier Name="ActorID" TypeName="System.Int32" />
</
Identifiers>
<
Methods>
<Method Name="GetPolicies">
<
Properties>
<
Property Name="RdbCommandText" Type="System.String">Select ActorID, PolicyID from v_Policies where ActorID = @ActorID</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>
</
FilterDescriptors>
<
Parameters>
<
Parameter Direction="In" Name="@ActorID">
<TypeDescriptor TypeName="System.Int32" IdentifierName="ActorID" AssociatedFilter="ID" Name="ActorID">
<DefaultValues>
<DefaultValue MethodInstanceName="PolicyFinderInstance" Type="System.Int32">0</DefaultValue>
</
DefaultValues>
</
TypeDescriptor>
</
Parameter>
<
Parameter Direction="Return" Name="Policies">
<
TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="PolicyDataReader">
<
TypeDescriptors>
<
TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="PolicyDataRecord">
<
TypeDescriptors>
<
TypeDescriptor TypeName="System.Int32" IdentifierName="ActorID" Name="ActorID" />
<
TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" Name="PolicyID" />
<TypeDescriptor Name="Test" TypeName="System.Int32"/>
</
TypeDescriptors>
</
TypeDescriptor>
</
TypeDescriptors>
</
TypeDescriptor>
</
Parameter>
</
Parameters>
<
MethodInstances>
<
MethodInstance Name="PolicyFinderInstance" Type="Finder" ReturnParameterName="Policies" />
<MethodInstance Name="policySpecificFinderInstance" Type="SpecificFinder" ReturnParameterName="Policies" />
</
MethodInstances>
</
Method>
<
Method Name="GetCreditLimitsForPolicy">
<
Properties>
<
Property Name="RdbCommandText" Type="System.String">
select PolicyID, ActorID, BuyerID, BuyerName from dbo.v_CreditLimits where PolicyID = @PolicyID
</Property>
<
Property Name="RdbCommandType" Type="System.String">Text</Property>
</
Properties>
<
Parameters>
<
Parameter Direction="In" Name="@PolicyID">
<
TypeDescriptor TypeName="System.Int32" IdentifierEntityName="CreditLimit" IdentifierName="PolicyID" Name="PolicyID" />
</
Parameter>
<
Parameter Direction="Return" Name="CreditLimits">
<
TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="CreditLimitDataReader">
<
TypeDescriptors>
<
TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="CreditLimitDataRecord">
<
TypeDescriptors>
<
TypeDescriptor TypeName="System.Int32" IdentifierEntityName="CreditLimit" IdentifierName="PolicyID" Name="PolicyID"/>
<
TypeDescriptor TypeName="System.Int32" IdentifierEntityName="CreditLimit" IdentifierName="ActorID" Name="ActorID"/>
<
TypeDescriptor TypeName="System.Int32" Name="BuyerID" />
<
TypeDescriptor TypeName="System.String" Name="BuyerName"/>
</
TypeDescriptors>
</
TypeDescriptor>
</
TypeDescriptors>
</
TypeDescriptor>
</
Parameter>
</
Parameters>
</Method>
</
Methods>
</
Entity>
</
Entities>
<
Associations>
<
Association AssociationMethodEntityName="Policy" AssociationMethodName="GetCreditLimitsForPolicy" AssociationMethodReturnParameterName="CreditLimits" Name="PolicyToCreditLimit" IsCached="true">
<SourceEntity Name="Policy" />
<
DestinationEntity Name="CreditLimit" />
</
Association>
</
Associations>
</
LobSystem>

What am I missing



Answer this question

Associations

  • villan_1

    Hans,

    From a quick glance I suggest you look at the following

    Here you have defined two identifiers

    <Identifiers>
    <
    Identifier Name="PolicyID" TypeName="System.Int32"
    />
    <
    Identifier Name="ActorID" TypeName="System.Int32"
    />
    </
    Identifiers
    >

    Here you only defined one field as an Indentifier

    <TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" Name="PolicyID"/>
    <
    TypeDescriptor TypeName="System.Int32" Name="ActorID"/>

    Replace the line above with this and it should work

    <TypeDescriptor TypeName="System.Int32" IdentifierName="ActorID" Name="ActorID"/>


    You have also only defined one parameter in your sql which I would expect 2 as you have defined this entity as requiring 2 values to identify it.

    <Parameters>
    <
    Parameter Direction="In" Name="@PolicyID"
    >
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" AssociatedFilter="ID" Name="PolicyID"
    >
    <
    DefaultValues>

    <Property Name="RdbCommandText" Type="System.String">
    select PolicyID, ActorID, BuyerID, BuyerName from dbo.v_CreditLimits where PolicyID = @PolicyID
    </Property
    >

    HTH,  

    Andrew



  • joseacta

    Thank you for your reply! It has helped me to better understand the BDC.

    I can make it work if I have single column keys in the database and only one identifier per entity. Unfortunately my data originates from a view, and I have a two column key.

    My appdef now looks like this:

    <Entities>
    <
    Entity EstimatedInstanceCount="10000" Name="CreditLimit">
    <
    Identifiers>
    <
    Identifier TypeName="System.Int32" Name="PolicyID" />
    <
    Identifier TypeName="System.Int32" Name="BuyerID"
    />
    </
    Identifiers>
    <
    Methods>
    <
    Method Name="GetCreditLimits">
    <
    Properties>
    <
    Property Name="RdbCommandText" Type="System.String">
    select PolicyID, ActorID, BuyerID, BuyerName from dbo.v_CreditLimits
    where PolicyID
    &gt;= @MinPolicyID and PolicyID &lt;
    = @MaxPolicyID
    and BuyerID
    &gt;= @MinBuyerID and BuyerID &lt;
    = @MaxBuyerID
    </Property>
    <
    Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property>
    </
    Properties>
    <
    FilterDescriptors>
    <
    FilterDescriptor Type="Comparison" Name="PolicyID"><Properties><Property Name="Comparator" Type="System.String">Equals</Property></Properties></FilterDescriptor>
    <
    FilterDescriptor Type="Comparison" Name="BuyerID"><Properties><Property Name="Comparator" Type="System.String">Equals</Property></Properties></FilterDescriptor>
    </FilterDescriptors>
    <
    Parameters>
    <
    Parameter Direction="In" Name="@MinPolicyID">
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" AssociatedFilter="PolicyID" Name="PolicyID">
    <
    DefaultValues>
    <
    DefaultValue MethodInstanceName="CreditLimitFinderInstance" Type="System.Int32">0</DefaultValue>
    <
    DefaultValue MethodInstanceName="CreditLimitSpecificFinderInstance" Type="System.Int32">0</DefaultValue>
    </
    DefaultValues>
    </
    TypeDescriptor>
    </
    Parameter>
    <
    Parameter Direction="In" Name="@MaxPolicyID">
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" AssociatedFilter="PolicyID" Name="PolicyID">
    <
    DefaultValues>
    <
    DefaultValue MethodInstanceName="CreditLimitFinderInstance" Type="System.Int32">9999999</DefaultValue>
    <
    DefaultValue MethodInstanceName="CreditLimitSpecificFinderInstance" Type="System.Int32">9999999</DefaultValue>
    </
    DefaultValues>
    </
    TypeDescriptor>
    </
    Parameter>
    <
    Parameter Direction="In" Name="@MinBuyerID">
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="BuyerID" AssociatedFilter="BuyerID" Name="BuyerID">
    <
    DefaultValues>
    <
    DefaultValue MethodInstanceName="CreditLimitFinderInstance" Type="System.Int32">0</DefaultValue>
    <
    DefaultValue MethodInstanceName="CreditLimitSpecificFinderInstance" Type="System.Int32">0</DefaultValue>
    </
    DefaultValues>
    </
    TypeDescriptor>
    </
    Parameter>
    <Parameter Direction="In" Name="@MaxBuyerID">
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="BuyerID" AssociatedFilter="BuyerID" Name="BuyerID">
    <
    DefaultValues>
    <
    DefaultValue MethodInstanceName="CreditLimitFinderInstance" Type="System.Int32">9999999</DefaultValue>
    <
    DefaultValue MethodInstanceName="CreditLimitSpecificFinderInstance" Type="System.Int32">9999999</DefaultValue>
    </
    DefaultValues>
    </
    TypeDescriptor>
    </
    Parameter>
    <
    Parameter Direction="Return" Name="CreditLimits">
    <
    TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="CreditLimitsDataReader">
    <
    TypeDescriptors>
    <TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="CreditLimitsDataRecord">
    <
    TypeDescriptors>
    <TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" Name="PolicyID" />
    <
    TypeDescriptor TypeName="System.Int32" Name="ActorID" />
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="BuyerID" Name="BuyerID" />
    <
    TypeDescriptor TypeName="System.String" Name="BuyerName" />
    </
    TypeDescriptors>
    </
    TypeDescriptor>
    </
    TypeDescriptors>
    </
    TypeDescriptor>
    </
    Parameter>
    </
    Parameters>
    <
    MethodInstances>
    <
    MethodInstance Type="Finder" ReturnParameterName="CreditLimits" ReturnTypeDescriptorName="CreditLimitsDataReader" ReturnTypeDescriptorLevel="0" Name="CreditLimitFinderInstance" />
    <
    MethodInstance Type="SpecificFinder" ReturnParameterName="CreditLimits" ReturnTypeDescriptorName="CreditLimitsDataReader" ReturnTypeDescriptorLevel="0" Name="CreditLimitSpecificFinderInstance"/>
    </
    MethodInstances>
    </
    Method>
    </
    Methods>
    </
    Entity>
    <
    Entity EstimatedInstanceCount="10000" Name="Policy">
    <
    Identifiers>
    <
    Identifier TypeName="System.Int32" Name="ActorID"
    />
    <
    Identifier TypeName="System.Int32" Name="PolicyID"
    />
    </
    Identifiers
    >
    <
    Methods>
    <
    Method Name="GetPolicies">
    <
    Properties>
    <
    Property Name="RdbCommandText" Type="System.String">
    Select ActorID, PolicyID from v_Policies
    where ActorID = @ActorID and PolicyID
    &gt;= @MinPolicyID and PolicyID &lt;= @MaxPolicyID
    </Property>
    <
    Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property>
    </
    Properties>
    <
    FilterDescriptors>
    <
    FilterDescriptor Type="Comparison" Name="ProfileActorID"><Properties><Property Name="Comparator" Type="System.String">Equals</Property></Properties></FilterDescriptor>
    <
    FilterDescriptor Type="Comparison" Name="MinMaxPolicyID"><Properties><Property Name="Comparator" Type="System.String">Equals</Property></Properties></FilterDescriptor>
    </
    FilterDescriptors>
    <
    Parameters>
    <
    Parameter Direction="In" Name="@ActorID">
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="ActorID" AssociatedFilter="ProfileActorID" Name="ActorID">
    <
    DefaultValues>
    <
    DefaultValue MethodInstanceName="PolicyFinderInstance" Type="System.Int32">0</DefaultValue>
    <
    DefaultValue MethodInstanceName="PolicySpecificFinderInstance" Type="System.Int32">0</DefaultValue>
    </
    DefaultValues>
    </
    TypeDescriptor>
    </
    Parameter>
    <
    Parameter Direction="In" Name="@MinPolicyID">
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" AssociatedFilter="MinMaxPolicyID" Name="PolicyID">
    <
    DefaultValues>
    <
    DefaultValue MethodInstanceName="PolicyFinderInstance" Type="System.Int32">0</DefaultValue>
    <
    DefaultValue MethodInstanceName="PolicySpecificFinderInstance" Type="System.Int32">0</DefaultValue>
    </
    DefaultValues>
    </
    TypeDescriptor>
    </
    Parameter>
    <
    Parameter Direction="In" Name="@MaxPolicyID">
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" AssociatedFilter="MinMaxPolicyID" Name="PolicyID">
    <
    DefaultValues>
    <
    DefaultValue MethodInstanceName="PolicyFinderInstance" Type="System.Int32">9999999</DefaultValue>
    <
    DefaultValue MethodInstanceName="PolicySpecificFinderInstance" Type="System.Int32">9999999</DefaultValue>
    </
    DefaultValues>
    </
    TypeDescriptor>
    </
    Parameter>
    <
    Parameter Direction="Return" Name="Policies">
    <
    TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="PolicyDataReader">
    <
    TypeDescriptors>
    <
    TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="PolicyDataRecord">
    <
    TypeDescriptors>
    <TypeDescriptor TypeName="System.Int32" IdentifierName="ActorID" Name="ActorID" />
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" Name="PolicyID" />
    </
    TypeDescriptors>
    </
    TypeDescriptor>
    </
    TypeDescriptors>
    </
    TypeDescriptor>
    </
    Parameter>
    </
    Parameters>
    <
    MethodInstances>
    <
    MethodInstance Type="Finder" ReturnParameterName="Policies" ReturnTypeDescriptorName="PolicyDataReader" ReturnTypeDescriptorLevel="0" Name="PolicyFinderInstance" />
    <
    MethodInstance Type="SpecificFinder" ReturnParameterName="Policies" ReturnTypeDescriptorName="PolicyDataReader" ReturnTypeDescriptorLevel="0" Name="PolicySpecificFinderInstance" />
    </
    MethodInstances>
    </
    Method>
    <
    Method Name="GetCreditLimitsForPolicy">
    <
    Properties>
    <
    Property Name="RdbCommandText" Type="System.String">
    select PolicyID, ActorID, BuyerID, BuyerName
    from dbo.v_CreditLimits
    where Polisenummer = @PolicyID
    </Property>
    <Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property>
    </
    Properties>
    <
    Parameters>
    <
    Parameter Direction="In" Name="@PolicyID">
    <
    TypeDescriptor TypeName="System.Int32" IdentifierName="PolicyID" Name="PolicyID" />
    </
    Parameter>
    <
    Parameter Direction="Return" Name="CreditLimits">
    <
    TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="CreditLimitDataReader">
    <
    TypeDescriptors>
    <
    TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="CreditLimitDataRecord">
    <
    TypeDescriptors>
    <
    TypeDescriptor TypeName="System.Int32" IdentifierEntityName="CreditLimit" IdentifierName="PolicyID" Name="PolicyID" />
    <
    TypeDescriptor TypeName="System.Int32" Name="ActorID" />
    <
    TypeDescriptor TypeName="System.Int32" IdentifierEntityName="CreditLimit" IdentifierName="BuyerID" Name="BuyerID" />
    <
    TypeDescriptor TypeName="System.String" Name="BuyerName" />
    </
    TypeDescriptors>
    </
    TypeDescriptor>
    </
    TypeDescriptors>
    </
    TypeDescriptor>
    </
    Parameter>
    </
    Parameters>
    </
    Method>
    </
    Methods>
    </
    Entity>
    </
    Entities>
    <
    Associations>
    <
    Association Name="PolicyToCreditLimit" AssociationMethodEntityName="Policy" AssociationMethodName="GetCreditLimitsForPolicy" AssociationMethodReturnParameterName="CreditLimits" AssociationMethodReturnTypeDescriptorName="CreditLimitDataReader" IsCached="true">
    <
    SourceEntity Name="Policy" />
    <
    DestinationEntity Name="CreditLimit" />
    </
    Association>
    </
    Associations>

    The error I get is this:

    Could not find fields to insert all the Identifier Values to correctly execute an Association with Name 'PolicyToCreditLimit'. Ensure input Parameters have TypeDescriptors associated with every Identifier defined for all the Source Entities in this Association.

    As far as I can see, I've provided enough TypeDescriptors with the IdentifierEntityName attribute.

    I'm starting to wonder if the BDC supports composite keys in associations at all...


  • xxfredxx

    I know this is an ancient chain, but in case someone searches for this error, I hit it myself and blogged about my solution here: