我有一个带有ID和BLOB的表的数据库。
我想要的是获取Blob,并从本质上将其流式传输到客户端,
而不是在内存中检索它。那是因为Blob可能真的很大(100 MB)。
我几乎使用SQLdataReader实现了这一目标。
这样做时,当我发出get请求时,它立即开始下载,并且没有内存开销。这是使用.net core 2.2
但是,当我切换到.net core 3.1时,现在它不起作用,并且内存被100兆字节填满。我也想使用实体框架来达到相同的结果,但是到目前为止,我还没有找到任何好的在线资源。
这是我到目前为止的代码。
[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
}
}
}
我已经试过像这样
public IEnumerable<byte[]> DownloadFile()
{
yield return context.t_noFs.Where(u => u.Id == 1)
.Select(u => u.dat).
FirstOrDefault();
}
尽管这确实返回了一个值,但是它没有达到预期的效果,并且会填满内存。
参考方案
在您的情况下,最佳实践是使用流。
[HttpGet]
public FileStreamResult 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;
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess)
var blobStream = reader.GetStream(0);
return new FileStreamResult(blobStream, "application/x-binary")
{
FileDownloadName = "your file name"
};
}
ASP.NET Web API 2中AuthorizeAttribute发生了什么变化? - c#我已经将项目和一组单元测试从ASP.NET Web API升级到ASP.NET Web API 2。我们将自定义DelegatingHandler用于自定义身份验证机制。它将Thread.CurrentPrincipal和HttpContext.Current.User设置为适当的System.Security.Claims.ClaimsPrincipal。…
Json参数转换继承Web API 2 - javascript我正在使用MS Web API 2使用ajax从我们的网页接收呼叫。然后,我有2个类:Subscriber和externalSubscriber。订户包含非常基本的数据,例如名称和ID。外部订户继承自订户并添加基本数据,例如地址和电子邮件。我有一个api方法来编辑这样定义的订户的数据:public IHttpActionResult PutSubscribe…
如何捆绑.Net Core API + Angular前端 - c#我有一个面向公众的有角前端,它碰到了.NetCore后端。使用webpack将两个项目捆绑在一起。问题是,我需要启用服务器端渲染,并且Microsoft已弃用/ made UseSpaPrerendering。我确实遵循了这个tutorial,但是它在.net core 3.0 / 3.1中根本无法很好地工作。当我开始工作时,我得到一个FOUC(未渲染内容的…
调用SignalR Hub不适用于Asp.Net Core Web API - c#我是SignalR的新手。我正在尝试设置一个Asp.Net Core WebAPI,以便其他客户端可以使用SignalR连接到它并获取实时数据。我的Hub类是:public class TimeHub : Hub { public async Task UpdateTime(string message) { await Clients.All.SendAs…
将多个对象从Angular控制器发布到Web API 2 - c#我能够从我的角度控制器发送原始json对象,该对象在我的Web api方法中反序列化为已知类型。很好,但是我现在需要能够在同一请求中发送其他参数,这些参数可以是json对象或简单类型,例如string或int。我看过诸如this之类的文章,它们准确地描述了我的问题,但是它们是从代码隐藏而不是客户端发送请求的。我试图构造一个json数组并将其发送进去,但收到以…