Asp.net-Web-Api

OData v4 Web API 2.2 深層擴展不起作用

  • May 13, 2016

情況

我正在嘗試將“項目”擴展到三個級別:

項目.產品.型號.類型

所以我稱之為嵌套查詢選項 url:

http://xxx/api/Items ? $ expand=Product( $ 展開=模型($展開=類型))

我收到一條警告說已達到最大深度 2,因此我將建議的 MaxExpansionDepth 屬性設置為 3。但是,“類型”屬性未返回!這個 SO question涵蓋了這一點

然後我查看了官方的 OData V4 標準,它說我應該在擴展選項中使用斜杠,如下所示:

http://xxx/api/Items ?$expand=Product/Model/Type

但這給了我一個錯誤告訴:

URI 中指定的查詢無效。找到遍歷多個導航屬性的路徑。請改寫查詢,使每個展開路徑僅包含類型段和導航屬性。

這個SO 答案涵蓋了哪些內容,但答案與官方 OData 文件相矛盾。這到底是什麼意思。

問題

在 OData v4 和 Web API 2.2 中使用 $expand 查詢選項的官方、標準和工作方式是什麼?

在與 Jerther 聊天后,我們將問題縮小到擴展屬性未標記為包含導航。結果,OData 框架正在刪除它們,因為它們沒有定義相應的實體集。更新模型以明確聲明收容似乎已經解決了這個問題。

根據使用的模型建構器,可以通過多種方式指定包含。在這種情況下,ODataConventionModelBuilder您可以將 添加System.Web.OData.Builder.ContainedAttribute到有問題的屬性中,而對於 ,ODataModelBuilder您可以在包含類ContainsMany<T>的實例上使用該方法。EntityTypeConfiguration

此外,目前,級聯擴展將在復雜類型包含實體類型的地方停止。

更新:

將鏈中的所有類型定義為 EntitySet 有效。

builder.EntitySet<Item>("Items");
builder.EntitySet<Product>("Products");
builder.EntitySet<Model>("Models");
builder.EntitySet<Type>("Types");

似乎將它們定義為EntityType還不夠。

見這裡:https ://github.com/OData/WebApi/issues/226

原始答案

我試圖重現你的情況,但不能。是否有可能沒有在您的操作中設置“類型”?這是我的小複製品

public class ItemsController : ODataController
{
   [HttpGet]
   [EnableQuery(MaxExpansionDepth = 10)]
   [ODataRoute("/Items")]
   public IHttpActionResult GetItems()
   {
       return this.Ok(CreateItem());
   }

   private Item CreateItem()
   {
       return new Item
       {
           Id = 1,
           Products = new Product[]
           {
               new Product
               {
                   Id = 2,
                   Models = new Model[]
                   {
                       new Model
                       {
                           Id = 3,
                           Types = new MyType[]
                           {
                               new MyType
                               {
                                   Id = 4,
                               },
                           },
                       },
                   },
               },
           },
       };
   }
}

使用**/Items 呼叫哪個? $ expand=Products( $ expand=Models($expand=Types))**結果如下:

{
   "@odata.context": "http://localhost:9001/$metadata#Items/$entity",
   "Id": 1,
   "Products@odata.context": "http://localhost:9001/$metadata#Items(1)/Products",
   "Products": [{
       "Id": 2,
       "Models@odata.context": "http://localhost:9001/$metadata#Items(1)/Products(2)/Models",
       "Models": [{
           "Id": 3,
           "Types@odata.context": "http://localhost:9001/$metadata#Items(1)/Products(2)/Models(3)/Types",
           "Types": [{
               "Id": 4
           }]
       }]
   }]
}

引用自:https://stackoverflow.com/questions/28488639