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
}]
}]
}]
}
情况
我正在尝试将 "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
}]
}]
}]
}