简体   繁体   中英

OData function returning a collection of entities fails with PowerQuery

I got this error while using PowerQuery on a OData service I'm currently developing:

When writing a JSON response, a user model must be specified and the entity set and entity type must be passed to the ODataMessageWriter.CreateODataEntryWriter method or the ODataFeedAndEntrySerializationInfo must be set on the ODataEntry or ODataFeed that is being written.

This occurs when invoking from PowerQuery a bound function that returns a collection of entities. When invoked from a web browser, the response is (JSON format):

{
    "@odata.context": "http://localhost:8080/ODataPrototype/ODataPrototype.svc/$metadata#Collection(Demo.ODataPrototype.Count)",
    "value": [
        {
            "RowCount": 1
        },
        {
            "RowCount": 2
        },
        {
            "RowCount": 3
        },
        {
            "RowCount": 4
        }
    ]
}

I use the Olingo V4 library. A stripped down version of my metadata would be:

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
  <edmx:DataServices>
    <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Demo.ODataPrototype">
      <EntityType Name="Instance">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" />
        <Property Name="Name" Type="Edm.String" />
        <Property Name="Description" Type="Edm.String" />
        <Property Name="Tag" Type="Edm.String" />
        <Property Name="Xid" Type="Edm.Int64" />
        <Property Name="Properties" Type="Collection(Demo.ODataPrototype.Property)" />
      </EntityType>
      <EntityType Name="Count">
        <Property Name="RowCount" Type="Edm.Int32" />
      </EntityType>
      <ComplexType Name="Property">
        <Property Name="Name" Type="Edm.String" />
        <Property Name="Value" Type="Edm.String" />
      </ComplexType>
      <Function Name="GetData" EntitySetPath="Instance/Demo.ODataPrototype.Count" IsBound="true">
        <Parameter Name="Instance" Type="Demo.ODataPrototype.Instance" />
        <Parameter Name="From" Type="Edm.DateTimeOffset" />
        <Parameter Name="To" Type="Edm.DateTimeOffset" />
        <ReturnType Type="Collection(Demo.ODataPrototype.Count)" />
      </Function>
      <EntityContainer Name="Container">
        <EntitySet Name="Instances" EntityType="Demo.ODataPrototype.Instance"></EntitySet>
        <EntitySet Name="Count" EntityType="Demo.ODataPrototype.Count" />
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

Would anyone know what I'm missing?

I found the solution. The context in my JSON response defines the result as a collection of type IVserver.ODataPrototype.Count:

"@odata.context": "http://localhost:8080/ODataPrototype/ODataPrototype.svc/$metadata#Collection(IVserver.ODataPrototype.Count)"

But PowerQuery needs an entityset:

"@odata.context": "http://localhost:8080/ODataPrototype/ODataPrototype.svc/$metadata#Count"

The EntitySet "Count" must be declared in the EntityContainer.

To get the EntitySet in the @odata.context, an entityset must be set when building the ContextURL. Example:

final ContextURL contextURL = ContextURL.with().entitySet(responseEdmEntitySet).selectList(selectList).serviceRoot(baseURI).build();

And, the methods asCollection() and type() must not be called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM