Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Webapi odata使用实体框架函数进行扩展_C#_Entity Framework_Asp.net Web Api_Odata - Fatal编程技术网

C# Webapi odata使用实体框架函数进行扩展

C# Webapi odata使用实体框架函数进行扩展,c#,entity-framework,asp.net-web-api,odata,C#,Entity Framework,Asp.net Web Api,Odata,我有一个产品odata控制器和一个产品类别odata控制器。 它们都使用实体框架实体,并具有用于odata扩展的导航方法。 两者的扩展都很好。 现在,我在entity framework中添加了一个存储过程来处理从数据库返回的数据,并且仍然返回一个“产品”记录。 我将实体存储过程函数返回类型设置为“Product”,并在Product odata控制器中创建了一个新函数来调用实体函数并返回“Product”。 我可以从url调用函数,这将正确返回产品实体/json。 现在我需要调用url上的扩展

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

我看过这篇文章,但这是基于非实体模型的。我的实体都是正确的,运行良好。

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

以下实施对我来说很有效:

WebApiConfig.cs
中:

builder.EntityType<Product>().Function("SomeFunction").ReturnsFromEntitySet<Product>("Products");
[HttpGet]
[EnableQuery]
public IHttpActionResult SomeFunction()
{
    return Ok(products.FirstOrDefault(c => c.ID == 1));
}
在浏览器中:

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

于2014年10月22日更新:

我已经修改了您附加的代码,并将其附加到下面。如果行得通,你会试试吗

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

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

这是我用来解决这个问题的代码。
绝对不是“正确”的代码。
例如:ODataQueryOptions.Top/Skip如果用于包含ODataActionParameters的操作,则将为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);
}
[HttpPost]
[启用查询]
公共页面结果SomeFunction(ODataQueryOptions选项、ODataActionParameters参数)
{
//从ODataActionParameters获取分页设置,因为它们没有显示在ODataQueryOptions上。也许将来会有一些解决方案。
int pageSize=(int)参数[“pageSize”];
int take=(int)参数[“take”];
int skip=(int)参数[“skip”];
int page=(int)参数[“page”];
//应用页面大小设置
ODataQuerySettings设置=新的ODataQuerySettings();
//创建临时结果集以保存存储过程的结果
var tempResults=db.SomeStoredProc().ToList();//需要ToList才能在分页之前获取“实际”总计数
//应用查询选项。目前,这仅用于获得正确的计数,因为在使用OData参数时,选项似乎不包含TOP/SKIP。
IQueryable results=options.ApplyTo(tempResults.AsQueryable(),settings);
//这是自定义分页所必需的。示例:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options
返回新的PageResult(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");
var SomeFunction=builder.Entity().Collection.Action(“SomeFunction”);
参数(“take”);
参数(“跳过”);
参数(“页面”);
参数(“页面大小”);
ReturnsCollectionFromEntitySet(“SomeObjects”);

您是正确的,因为“EnableQuery”确实适用于扩展。我应该更好地解释我的问题。在使用StoredProcess和分页时,“EnableQuery”似乎不起作用。比如“PageResult”…@goroth为什么要使用PageResult,因为您描述了返回值将是单个“产品”记录。但是,如果您将产品集合与分页一起返回,则可以使用“[EnableQuery(PageSize=10)]”将返回类型设置为“IQueryable”。关键字是“StoredProcess”。由于存储过程总是返回所有记录,我想我必须使用“PageResults”首先获取“total count”,然后在返回结果上设置“take/skip”。
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");