【问题标题】:Stream data from database to browser as JSON via ASP.NET Core通过 ASP.NET Core 以 JSON 格式将数据从数据库流式传输到浏览器
【发布时间】:2018-06-13 13:50:41
【问题描述】:

我有一个需要返回大量 JSON 数据的 API。我正在尝试将其直接从数据库流式传输到客户端,以避免占用我的 Web 服务器上的 RAM。这是一个好方法吗? (似乎正在工作)

[HttpGet]
[Route("data")]
public IEnumerable<MappedDataDto> GetTestData()
{
    var connection = new NpgsqlConnection(_connectionString);
    connection.Open();

    IEnumerable<RawDataDto> rawItems = connection.Query<RawDataDto>("SELECT * FROM sometable", buffered: true);

    foreach (var rawItem in rawItems)
    {
        var mappedItem = Map(rawItem);
        yield return mappedItem;
    }
}
  • 我需要处理连接还是会自动处理?我可以将它包装在 i using 块中,因为这会引发“无法访问已处理的对象”之类的异常
  • 使用某种流而不是yield return会更好吗?

编辑: 在我的例子中,我们有一个大型的遗留 javascript Web 应用程序,它显示两个日期之间的数据图表。客户端下载整个数据集并在客户端上进行内存计算以以不同的方式表示该数据(用户可以创建自己的自定义仪表板,因此并非每个人都以相同的方式使用数据)。

我们的问题是,当客户端请求一个包含大量数据的周期时,我们的 ASP.NET Core API 的内存消耗会增加很多。所以这就是我们试图阻止的。

不幸的是,对客户端进行任何较大的更改都会非常耗时,因此我们正在研究可以在 API 端做些什么。

这就是为什么我试图弄清楚是否有一种方法可以通过 API 从数据库中流式传输数据。这样就不需要对客户端进行任何更改,并且 API 的内存消耗不会那么糟糕,因为它不必将所有内容都保存在内存中。

【问题讨论】:

  • 当非托管对象实现 IDisposable 时,您应该始终对其进行处置。如果您将连接包装在 using 块中,这将是自动的。 “这会是一种好方法吗”的答案似乎是主观的,但它绝对是一种方法。
  • @DanWilson 相反,在这里使用using 会导致异常,因为对象在before 序列化甚至可以开始之前被释放。 代码无法正常工作
  • 要发送的列表或数据有多大?我建议实现分页,并让客户端应用程序根据需要请求数据。不过,这取决于您的要求,您介意解释一下您的功能吗?
  • @RuiJarimba 是对的。分页是适当的路径。您希望限制 SQL 查询运行时间的可能原因是它需要很长时间和/或资源繁重。分页部分解决了这个问题,因为您不需要一次查询所有数据。除此之外,您应该实现存储过程和/或寻找其他方法来优化数据库端的查询。无论如何,您不能同时返回 JSON 和流。所有数据都必须最终加载到内存中以将其序列化为 JSON 字符串。
  • 这里有多个活动部件,因此内存利用率将根据每个部件的工作方式而有所不同。然而,true 流式传输意味着发送Transfer-Encoding: chunked 并在客户端可用字节时实际提供它们。这永远不会在这里发生。 ASP.NET Core 始终需要完全实现查询结果才能创建 JSON 响应。

标签: c# asp.net-core dapper


【解决方案1】:

鉴于功能(在图表/图形中显示数据),我建议对客户端和服务器应用程序进行一些更改。

让我们假设这种情况:

客户请求数据 30 天,对应 100 万行

这意味着不仅在服务器上而且在客户端应用程序上都会有很大的内存消耗!因此,我建议重写查询以按天、小时甚至更短的时间段对数据进行分组,只要满足您的需求 - 这将减少从服务器发送的数据量: p>

  • 按天分组:30 条记录
  • 按小时分组:720 条记录
  • 按 10 分钟分组范围:4320 条记录
  • 按分钟分组:43200条记录

客户端应用程序显然需要进行一些更改才能根据分组数据而不是每一行进行计算。

顺便说一句,我不知道您使用的是哪个 RBDMS,但这可能会有所帮助(SQL Server): How to group time by hour or by 10 minutes

【讨论】:

    猜你喜欢
    • 2016-06-24
    • 1970-01-01
    • 2011-04-21
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    • 2011-05-05
    • 2015-09-21
    • 2023-04-04
    相关资源
    最近更新 更多