2014-10-02 57 views
4

我有一个包含文件记录的SQL Server 2012表。每个记录都有一个varbinary(max)BlobData,表示存储在文件中的数据 - 数据大小可能超过1 GB,并且不能放入RAM,因此我不希望它支持字节数组。我想实现两个流式操作:使用实体框架流式传输varbinary(max)数据6

  • 顺序读取BlobData行块成缓冲区;
  • 使用缓冲区以块为单位顺序覆盖BlobData行。

使用普通ADO.NET,一个简单的方法来实现这一目标是通过使用SqlDataReaderUPDATE .WRITE()

// 1. Sequentially read varbinary(max) into a buffer 
using (SqlDataReader reader = sqlCommand.ExecuteReader(System.Data.CommandBehavior.SequentialAccess)) 
{ 
    while (reader.Read()) 
    { 
     byte[] buffer = new byte[size]; 

     while ((count = reader.GetBytes(0, offset, buffer, 0, buffer.Length)) > 0) 
     { 
      DoStuffWithBuffer(buffer); 
      offset += count; 
     } 
    } 
} 

// 2. Sequentially overwrite varbinary(max) from a buffer - iterate: 
UPDATE [File] SET [BlobData].WRITE(@buffer, @offset, @count) 
WHERE [FileID][email protected] 

据我所知,这样的操作并非EF在过去的范围之内我最好的选择就是坚持使用ADO.NET。但是,我注意到EF6有一些新的方法,例如EntityDataReader.GetBytes(),引用MSDN,»从指定的列开始,从dataIndex指示的位置开始读取字节流到缓冲区,从bufferIndex指示的位置开始。

  1. 我的理解是EntityDataReader.GetBytes()类似于SqlDataReader.GetBytes()和应该提供大致相同的性能 - 我是正确还是有其他考虑?

  2. EF6有没有办法在varbinary(max)列上执行类似于UPDATE .WRITE(buffer, offset, count)的操作?

我的解决方案的其他部分使用EF6,所以为了保持一致性,我最好还是使用EF6来实现所有这些。

鉴于新的EF6功能,我可以/应该使用EF6来实现这个功能,还是应该坚持以前的建议ADO.NET?我正在使用.NET 4.0。

+1

你有没有得到解决这个? – camainc 2015-11-25 20:15:46

+1

@camainc不幸的是我没有 - 我不知道如果在这一点上这是可以通过EF做的。 – w128 2015-11-25 20:33:17

回答

0

有点晚了,也许 - 但context.Database.ExecuteSqlCommand接受流作为参数,即

var id = 1234; 
var blobStream = await someSource.ReadAsStreamAsync(); // obtain some stream 
db.Database.ExecuteSqlCommand($"UPDATE MyTable set [email protected] 
           where [email protected]", blobStream, id);