OData v4 Web API 2.2 深层次扩展不工作

OData v4 Web API 2.2 deep level expand not working

情况

我正在尝试将 "Item" 扩展到三个级别:

Item.Product.Model.Type

所以我称这个嵌套查询选项为url:

http://xxx/api/Items?$expand=产品($expand=型号($expand=类型))

我收到一条警告,指出已达到最大深度 2,因此我将建议的 MaxExpansionDepth 属性设置为 3。但是,"Type" 属性 没有返回! this SO question

然后我查看 official OData V4 standard,它说我应该在展开选项中使用斜杠,如下所示:

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

但这给了我一个错误提示:

The query specified in the URI is not valid. Found a path traversing multiple navigation properties. Please rephrase the query such that each expand path contains only type segments and navigation properties.

SO answer 涵盖的内容,但答案与官方 OData 文档自相矛盾。这到底是什么意思。

问题

使用 OData v4 和 Web 的深层查询选项的官方、标准和工作方式是什么 API 2.2

在聊天中与 Jerther 合作后,我们将问题缩小到未标记为包含导航的扩展属性。因此,OData 框架正在删除它们,因为它们没有定义相应的实体集。更新模型以明确声明包含似乎已经解决了问题。

可以通过多种方式指定包含,具体取决于所使用的模型构建器。在 ODataConventionModelBuilder 的情况下,您可以将 System.Web.OData.Builder.ContainedAttribute 添加到有问题的 属性 中,而对于 ODataModelBuilder 您可以在 EntityTypeConfiguration 包含 class.

的实例

此外,目前,级联扩展将在复杂类型包含实体类型的地方停止。

更新:

将链中的所有类型定义为 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

原答案

我试过重述你的情况,但不行。 "Types" 是否可能未在您的操作中设置?这是我的小复制品

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
            }]
        }]
    }]
}