Webapi odata扩展了实体框架功能

时间:2014-10-16 13:33:27

标签: c# entity-framework asp.net-web-api odata

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

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

2 个答案:

答案 0 :(得分:2)

根据您的描述,您似乎需要将[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和分页。您无需担心将它们应用于您的结果。来自客户端的查询选项将应用于您返回的整个集合。

答案 1 :(得分:1)

以下是我用来解决问题的代码 绝不是“正确”的代码 例如:如果在包含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");