I have a database with a table that has an id and a BLOB. What i want is to get the blob and essentially stream it to the client, and not retrieve it in memory. That is because the blob can be really big (100s of MB).
I have almost achieved this using SQLdataReader. Doing this, when i make a get request, it starts downloading immediately, and there is no overhead on memory. This was using .net core 2.2 However, when I switched to .net core 3.1, now it doesn't work, and the memory gets filled up with 100s of megabytes. I would also like to achieve the same result using entity framework, but till now i haven't found any good online resources.
Here is the code I have up until now.
[HttpGet]
public IEnumerable<Byte[]> GetStreaming()
{
var header = Request.Headers["Accept-Encoding"];
System.Console.WriteLine(header);
string connectionString = "Data Source=myPc\\SQLEXPRESS;Initial Catalog=dbo;Persist Security Info=True;User ID=sa;Password=admin";
//----------------------
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
SqlCommand command = new SqlCommand("exec getBlob", connection);
SqlTransaction tran = connection.BeginTransaction(IsolationLevel.ReadCommitted);
command.Transaction = tran;
byte[] buffer = new byte[5000000];
long position = 0;
long bytesRead = 5000000;
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
reader.Read();
reader.GetBytes(0, position, null, 0, 5000000);
while (bytesRead == 5000000)
{
// Get the pointer for file
bytesRead = reader.GetBytes(0, position, buffer, 0, 5000000);
position += bytesRead;
yield return buffer;
// Create the SqlFileStream
}
}
}
I've tried just doing it like this
public IEnumerable<byte[]> DownloadFile()
{
yield return context.t_noFs.Where(u => u.Id == 1)
.Select(u => u.dat).
FirstOrDefault();
}
and while this does return a value, it doesn't have the desired effect and fills the memory up.