如何将大型二进制数据流式传输到SQL Server

时间:2010-12-30 18:59:42

标签: sql-server asp.net-mvc linq-to-sql ado.net scalability

我有一个用ASP.NET MVC编写的带有SQL Server后端的Web服务。客户端可以在调用Web服务时发送大量数据,每个数据大小为10兆字节。

在服务器端,我想读取HTTP请求流并将其写入SQL表中的VARBINARY字段。 如何在不将整个流读入内存数组的情况下执行此操作

我担心内存的原因是这个系统需要扩展到1000个并发客户端(至少)。

我目前正在使用Linq to SQL,它看起来不支持数据流,因为Linq Binary类型只能使用字节数组进行初始化。

还有其他方法可以使用Linq to SQL吗?

如果使用Linq to SQL无法做到这一点,我该如何使用ADO.NET或其他方法做到这一点?

2 个答案:

答案 0 :(得分:2)

您可以将数据流式传输到磁盘,然后使用OPENROWSET执行批量导入数据。例如:

INSERT INTO YOURTABLE(binaryColumnName) 
SELECT * FROM 
OPENROWSET(BULK N'C:\data.bin', SINGLE_BLOB)

您可以使用temp file APIs来避免管理磁盘上数据的生命周期......一旦不再使用,它​​将被删除。

答案 1 :(得分:1)

我相信你可以使用UPDATE语句的.WRITE子句来进行分块数据插入。如果您正在使用LINQ,则需要从数据上下文对象创建两个命令。第一个创建(INSERT)将包含数据的行。第二个是使用.WRITE子句的UPDATE语句。参数化数据和偏移值。循环执行UPDATE语句的次数与“块”一样多。

插入XrayImages(HeaderId,ImageBytes)VALUES(@headerId,@ imageValue)

UPDATE XrayImages SET ImageBytes.WRITE(@imageChunk,NULL,@ chunkLength WHERE ImageId = @imageId;

有关详细信息,请查看此MSDN文章:http://msdn.microsoft.com/en-us/library/bb399384.aspx


我很确定在调用Controller代码时,已收到整个请求(并且已在内存中)。我的基础是,Request.Files集合已经知道有多少文件及其长度。对于多部分表单,我知道如何确定这一点的唯一方法是阅读整个请求。我不知道无论如何要在MVC中更改它,所以你可能必须编写一个处理器来执行实际的文件上传。

这里有很多变量需要考虑。根据将同时上载数据的1000个并发客户端的数量,您需要在数据库服务器和Web服务器之间使用多个GB数。您还需要数据库服务器上的I / O功能,这些功能将超出我的经验。

我会认真考虑将文件保存到基于文件系统的位置并在数据库中包含元信息,特别是如果您可以将文件保存在Web服务器上。否则,我认为使用SqlServer的FileStream功能比纯表解决方案更具可扩展性。

希望有所帮助!