【问题标题】:OData v4 Web API 2.2 deep level expand not workingOData v4 Web API 2.2 深层扩展不起作用
【发布时间】:2015-04-13 20:21:07
【问题描述】:

情况

我正在尝试将“项目”扩展到三个级别:

Item.Product.Model.Type

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

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

我收到一条警告说最大深度已达到 2,因此我将建议的 MaxExpansionDepth 属性设置为 3。但是,“类型”属性没有返回!这被this SO question覆盖了

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

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

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

URI 中指定的查询无效。找到遍历多个导航属性的路径。请改写查询,使每个展开路径仅包含类型段和导航属性。

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

问题

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

【问题讨论】:

    标签: asp.net-web-api odata


    【解决方案1】:

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

    可以通过多种方式指定遏制,具体取决于所使用的模型构建器。对于ODataConventionModelBuilder,您可以将System.Web.OData.Builder.ContainedAttribute 添加到相关属性中,而对于ODataModelBuilder,您可以在包含类的EntityTypeConfiguration 实例上使用ContainsMany<T> 方法。

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

    更新:

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

    【讨论】:

    • 正如我在问题中所说,属性设置为3。我也尝试了4,没有变化。
    • 对不起!我将无法阅读归咎于我的小设备。如果我什么都没有,我会在上面讨论并删除这个答案。
    • np。我已经为此研究了好几个小时,如果您发现任何感兴趣的内容,请告诉我。
    • 我已经用我尝试过的方法重写了答案,也许它会给你一个想法。
    • 我尝试了同样的方法,但没有返回类型:pastebin.com/n2VtfDPm 另外,我正在使用 ODataController 和 ODataConventionModelBuilder。我认为我们正在做某事
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    • 2016-02-27
    • 2017-05-25
    • 1970-01-01
    相关资源
    最近更新 更多