Нашел это решение с передачей Stream. В основном, используя поток Respose.Body от клиента asp. net mvc и изменяя его напрямую, не возвращая никаких данных. Таким образом, при получении файла начинается отправка фрагментов напрямую клиенту без использования всей памяти сервера (за раз указывается только этот 1 МБ).
var sql = $@"
SELECT [Data]
FROM {TableName}
WHERE ChunkId = @chunkId";
using (var conn = this.dbConnectionFactory.GetSqlConnection)
using (var reader = await conn.ExecuteReaderAsync(sql, new { chunkId }).ConfigureAwait(false))
{
while (reader.Read())
{
var buffer = new byte[1024 * 1024]; // Read chunks of 1MB
var bytesRead = 0L;
var dataIndex = 0L;
while ((bytesRead = reader.GetBytes(0, dataIndex, buffer, 0, buffer.Length)) > 0)
{
var actual = new byte[bytesRead];
Array.Copy(buffer, 0, actual, 0, bytesRead);
await stream.WriteAsync(actual, 0, (int)bytesRead).ConfigureAwait(false);
dataIndex += bytesRead;
}
}
}