OData v4 Web API 2.2 深層擴展不起作用
情況
我正在嘗試將“項目”擴展到三個級別:
項目.產品.型號.類型
所以我稱之為嵌套查詢選項 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 }] }] }] }