我总是在OData控制器上返回一个IEnumerable对象。但是由于表开始大到足以填满缓冲区,我开始返回一个List,就像这里一样:
[HttpGet("table1")]
[EnableQuery()]
public async Task<List<Table1>> GetAllTable1()
{
var values = await _mediator.Send(new Table1GetAllODataRequest { });
return values.ToList();
}
在开始返回List之后,表不再填充缓冲区,但$expand不起作用,它总是返回null,如下所示:
{
"equipment": null,
"equipmentId": 452,
"id": 1
}
预期结果是:
{
"equipment": {
"code": "ABC",
"description": "ABCD1",
"enabled": false,
"id": 452
},
"equipmentId": 452,
"id": 1
}
当我做";ToList";它丢失了设备表的引用。
我正在做的请求如下:
https://localhost:44382/api/odata/table1?$expand=equipment
有人知道在这种情况下该怎么办吗?我无法返回IEnumerable,因为它在缓冲区中填充了太多数据。
您的Mediator实现返回的内容并不直观,但我的猜测是,在一种情况下,请求中序列化的数据延迟加载相关数据(这会非常慢,尤其是在处理结果集合时(,或者不知怎的急于加载数据,而在当前情况下则不是。你可以让你的调解员急切地加载相关数据,但你几乎肯定会点击你的";缓冲区";障碍(我猜是响应大小(
最终,当通过HTTP处理数据时,您会遇到一个障碍,即请求的数据太大,无法发送,或者无法发送到客户端。你需要考虑以下几点:
-
分页:这使您的视图能够加载数据页面,比如一次50-100行,并向用户显示选择页面,或者使用动态滚动系统以分段加载其他数据。这允许您加载所需的详细级别,无论数据源有多大,都不会触及内存或请求大小的边界。
-
投影:这是将视图绑定到的内容从原始实体图更改为仅包含视图实际需要的表中字段的视图模型或DTO。这是在EF中使用
Select()
或通过Automapper的ProjectTo()
方法完成的。很少需要每个相关表中的每一列,因此投影可以大大减少视图显示所需的每一行的内存/传输。 -
异步扩展:当呈现受益于能够";向下钻取";为了根据需要显示越来越多的详细信息,您可以选择在加载视图时立即传递所有信息,或者在实际需要时传递基本信息并请求更多详细信息。一个典型的例子是,您可以使用选项卡或可展开区域来获取相关信息。您可以在加载页面时加载并传递所有这些信息,即使80%的时间没有人使用它,也可以将主视图总结为屏幕上可见的内容,并在用户扩展到真正想要查看详细信息时发出快速Ajax请求以获取详细信息。一个典型的例子是表的搜索结果。这些通常显示单行字段,因此将这些摘要和相关ID投影到摘要视图模型中,然后当用户想要选择一个来获取详细信息时,执行Ajax调用或导航到详细视图以按ID获取详细信息。