Webapi odata扩展了实体框架功能

本文关键字:框架 功能 实体 odata 扩展 Webapi | 更新日期: 2023-09-27 18:26:49

我有一个产品odata控制器和一个产品类别odata控制器
它们都使用实体框架实体,并具有用于odata扩展的导航方法
两者的扩展都运行良好
现在,我在实体框架中添加了一个存储过程来处理从数据库返回的数据,并且仍然返回一个"Product"记录
我将实体存储过程函数返回类型设置为"Product",并在Product odata控制器中创建了一个新函数来调用实体函数并返回"Product"
我可以从url调用函数,这将正确返回一个Product实体/json
现在我需要调用url上的expand来获取"产品类别"实体,但这失败了。

我看过这篇文章,但它是基于非实体模型的。我的实体都是正确的,运行良好
http://beyondtheduck.com/projecting-and-the-odata-expand-query-option-possible-at-last-kinda/

Webapi odata扩展了实体框架功能

根据您的描述,似乎需要将[EnableQuery]属性添加到存储过程的控制器方法中。

以下实现对我有效:

WebApiConfig.cs:中

builder.EntityType<Product>().Function("SomeFunction").ReturnsFromEntitySet<Product>("Products");

ProductsController.cs:中

[HttpGet]
[EnableQuery]
public IHttpActionResult SomeFunction()
{
    return Ok(products.FirstOrDefault(c => c.ID == 1));
}

在浏览器中:

GET http://localhost:54017/Products(1)/Default.SomeFunction()?$expand=Categories

给出

{
    @odata.context: "http://localhost:54017/$metadata#Products",
    value: [
    {
        ID: 1,
        Name: "Some",
        Categories: [
        {
            ID: 1,
            Name: "Some"
        }
        ]
    }
    ]
}

2014年10月22日更新:

我已经修改了你所附的代码,并将其附在下面。如果有效,你会试试吗?

[HttpPost]
[EnableQuery(PageSize=10)]
public IHttpActionResult SomeFunction()
{
    var results = db.SomeStoredProc().ToList();
    return Ok(results);
}

类似的功能在我的测试中起作用。这样做的原因是Web API OData自动为您处理$skip$top和分页。你不需要担心将它们应用到你的结果中。来自客户端的查询选项将应用于您返回的整个集合。

这是我用来解决这个问题的代码
这绝不是"正确"的代码
例如:如果在包含ODataActionParameters的Action上使用,则ODataQueryOptions.Top/Skip将为null
ODataActionParameters将包含Top/Skip作为参数?很奇怪
所以我添加了两者,希望微软或其他人将来能解决这个问题。

控制器:

[HttpPost]
[EnableQuery]
public PageResult<SomeObject> SomeFunction(ODataQueryOptions<SomeObject> options, ODataActionParameters parameters)
{
    // Get the paging settings from ODataActionParameters since they are not shown on the ODataQueryOptions. Maybe there will be some fix for this in the future.
    int pageSize = (int)parameters["pageSize"];
    int take = (int)parameters["take"];
    int skip = (int)parameters["skip"];
    int page = (int)parameters["page"];
    // Apply page size settings
    ODataQuerySettings settings = new ODataQuerySettings();
    // Create a temp result set to hold the results from the stored procedure
    var tempResults = db.SomeStoredProc().ToList(); // ToList is required to get the "real" total count before paging
    // Apply the query options. For now this is only needed to get the correct count since the options does not seem to contain the TOP / SKIP when using OData parameters.
    IQueryable results = options.ApplyTo(tempResults.AsQueryable(), settings);
    // This was needed for custom paging. EXAMPLE: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options
    return new PageResult<SomeObject>(tempResults.Skip(skip).Take(take),
                            Request.ODataProperties().NextLink,
                            Request.ODataProperties().TotalCount);
}

然后WebApiConfig:

var SomeFunction = builder.Entity<SomeObject>().Collection.Action("SomeFunction");
SomeFunction.Parameter<int>("take");
SomeFunction.Parameter<int>("skip");
SomeFunction.Parameter<int>("page");
SomeFunction.Parameter<int>("pageSize");
SomeFunction.ReturnsCollectionFromEntitySet<SomeObject>("SomeObjects");