OData V4:是否可以只从父实体中选择字段(即导航属性)?

问题描述 投票:0回答:1

在OData V3中,我只能从父/祖先实体中选择字段,如下所示:http://services.odata.org/V3/Northwind/Northwind.svc/Order_Details(OrderID=10248,ProductID=11)?& $ select = Product / Category / CategoryName&$ expand = Product / Category

该查询仅返回CategoryName,它不包括Order_Details或Product中的任何字段。出于性能原因,此行为对我们的应用程序非常重要。在我们不需要它们时选择所有字段会对查询性能产生重大影响。

在OData V4中似乎没有办法实现相同的目标。等效查询返回Order_Details和Product http://services.odata.org/V4/Northwind/Northwind.svc/Order_Details(OrderID=10248,ProductID=11)中的所有字段?$ expand = Product($ expand = Category($ select = CategoryName))

我能得到的最接近的是从每个级别中选择一个字段,在我们的代码中引入了很多复杂性,并且很难确保所有查询(未来和现有)都遵守此规则。

select odata expand odata-v4
1个回答
0
投票

最简单的解决方案是在数据库服务器上创建具有所需模式的View,并尝试使用过滤器和列名称从此数据源获取数据。

特别是在面对性能问题时。

最好的方法是将此类作为单例注册到IoC

public class InternalODataEdmModelBuilder
{
    private readonly ODataConventionModelBuilder _oDataConventionModelBuilder = new ODataConventionModelBuilder();
    private IEdmModel _edmModel;

    public InternalODataEdmModelBuilder()
    {
        ODataEntitySetsConfigInternal.Register(_oDataConventionModelBuilder);
    }

    // cache
    public IEdmModel GetEdmModel()
    {
        return _edmModel ?? (_edmModel = _oDataConventionModelBuilder.GetEdmModel());
    }
}

internal static class ODataEntitySetsConfigInternal
{
    public static void Register(ODataConventionModelBuilder oDataModelBuilder)
    {
        if (oDataModelBuilder == null)
        {
            throw new Exception("'ODataConventionModelBuilderWebApi' cannot be null");
        }

        oDataModelBuilder.EntitySet<YourView>("YourView").EntityType.HasKey(x => x.YourKey);
    }
}

然后在API控制器中注入此注册对象,并从URL构建您的查询,如下所示:

        ODataQueryContext queryContext = new ODataQueryContext(_oDataConventionModel, typeof(YourViewEFType), null);
        var option = new ODataQueryOptions(queryContext, Request);
        var data = option.ApplyTo(data, new ODataQuerySettings { EnsureStableOrdering = false });

然后将数据映射到您的POCO(向公众展示的API EDM模型)。

希望这可以帮助。

© www.soinside.com 2019 - 2024. All rights reserved.