首页 > 解决方案 > 缺少 OData 信封/上下文

问题描述

当我通过 OData 请求一些数据时,我将按请求获取数据,但不是 OData 信封/上下文。这意味着任何 OData 功能都不适用于客户端。

我试图了解我没有将 OData 信封与数据一起获取的原因。

设置如下:

我正在使用此 url 请求数据:http://localhost:5000/odata/mycontroller/mydbview。

控制器类:

public class MyController : ODataController
{
    [EnableQuery]
    [ODataRoute("MyController/MyDBView")]
    public IActionResult GetSeasonView(int id)
    {
        var requestedItems = myTableContext.MyDBView;

        return Ok(requestedItems);
    }
}

电火花模型:

public static IEdmModel GetEdmModel()
{
    var odataModelBuilder = new ODataConventionModelBuilder();
    odataModelBuilder.EntitySet<MyDataDto>("My");

    return odataModelBuilder.GetEdmModel();
}

数据对象如下所示:

[Table("datatable", Schema = "api")]
public class MyDataDto
{
    [Key] 
    public string Id { get; set; }
    public string Status { get; set; }
    public uint Total { get; set; }
  
    <Continues with more data>

该视图是数据表的子集,如下所示:

[Table("datatable", Schema = "api")]
public class MyDBView
{
    [Key]
    public string id { get; set; }
    public string status { get; set; }
    public uint total { get; set; }
}

对此设置可能有什么问题有任何建议吗?顺便说一句,我试图遵循本指南:https ://www.laboremus.ug/post/using-sql-views-with-entity-framework-code-first

更新

我找到了问题,但仍然没有解决方案。问题是实体集注册为 MyDataDTO 而返回值是 MyDBView。

我仍然不知道解决方案。

标签: .net-coreodata

解决方案


有一些问题,您的预期路线不符合 OData,这使得您难以解释您的预期用途,这是一个集合还是基于项目的请求?例如,您有一个未在方法中使用的 'id' 参数,并且路由前缀MyController与通过路由注册的控制器不匹配My

对于此解决方案,我可以演示两种方案的配置:

  • 一个集合绑定函数返回整个视图
  • 一个项目绑定函数,用于返回范围为给定项目 ID 的视图

如果要在端点方法上使用 作为响应类型,则需要将View DTO注册到 OData 模型,或者可以 return 。IActionResultIQueryable<MyDbView>

  • 这可以工作,因为现在属性路由可以识别要返回的预期类型
  • IActionResult让您可以灵活地返回错误响应或其他标准形式的响应。

让我们看看这个视图的两种方法,一种返回整个视图并支持$filter查询选项,另一种从视图中返回单个项目的记录:

注意:我已经更改了您示例中的方法名称,以减少与配置的混淆

public class MyController : ODataController
{
    // example route: ~/My/DBView
    [EnableQuery]
    [HttpGet]
    public IActionResult DBView()
    {
        var requestedItems = myTableContext.MyDBView;
        return Ok(requestedItems);
    }

    // example route: ~/My(id)/asDBView
    [EnableQuery]
    [HttpGet]
    public IActionResult AsDBView(int key)
    {
        var requestedItem = myTableContext.MyDBView.Where(x => x.Id == key);
        return Ok(requestedItems);
    }
}

现在我们关心通过IEdmBuilder. 对于支持查询的视图,您需要指定数据集的概念名称,但这不需要对应于实际的控制器。

public static IEdmModel GetEdmModel()
{
    var odataModelBuilder = new ODataConventionModelBuilder();
    // Initialize your OData EntitySets
    odataModelBuilder.EntitySet<MyDataDto>("My");

    // initialize the Custom DTOs
    odataModelBuilder.EntitySet<MyDbView>("MyDbViewFakeSet"); 
    // NOTE: Name is arbitrary, but MUST be unique across all EntitySets.

    // Register the Function endpoints on your "My" controller
    odataModelBuilder.EntitySet<MyDataDto>("My")
                     .Collection.Function("DBView")
                     .ReturnsCollectionFromEntitySet<MyDbView>("MyDbViewFakeSet");

    odataModelBuilder.EntitySet<MyDataDto>("My")
                     .EntityType.Function("asDBView")
                     .ReturnsFromEntitySet<MyDbView>("MyDbViewFakeSet");


    return odataModelBuilder.GetEdmModel();
}

推荐阅读