I'm trying to query a varbinary
column that contain a file (1,2 Gb).
I'm using Entity Framework. See below:
Database to test
CREATE TABLE [dbo].[BIGDATA]
(
[id] [bigint] IDENTITY(1,1) NOT NULL,
[BIGDATA] [varbinary](max) NULL,
CONSTRAINT [PK_BIGDATA] PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY]
Data to test (any file with 1 Gb)
INSERT INTO [dbo].[BIGDATA]([BIGDATA])
VALUES
((SELECT BulkColumn FROM OPENROWSET(BULK N'C:\BigTest.txt', SINGLE_BLOB) AS Document))
Controller to download file
public FileResult Download()
{
try
{
var context = new Models.ELOGTESTEEntities();
var idArquivo = Convert.ToInt32(1);
// The problem is here, when trying send command to SQL Server to read register
var arquivo = (from item in context.BIGDATA
where item.id.Equals(idArquivo)
select item).Single();
var mimeType = ".txt";
byte[] bytes = System.Text.Encoding.GetEncoding("iso-8859-8").GetBytes("BigTest.txt");
return File(arquivo.BIGDATA1, mimeType, System.Text.Encoding.UTF8.GetString(bytes));
}
catch (Exception ex)
{
throw ex;
}
}
I can querying normally on SQL Server with Select * From BigData
.
But, in Entity Framework (or command with ADO) I get this exception:
System.OutOfMemoryException
Does someone know how fix this problem?
Wow that is a lot data. I really think you need to not use EF to get this data, but instead use the good 'ol SqlDataReader.
Given your .net 4.0 restriction, I found a custom implementation of streaming a read from a massive varbinary column. I can't take any credit for this other than reviewing the code and making sure there are not .net 4.5 shortcuts in it:
http://www.syntaxwarriors.com/2013/stream-varbinary-data-to-and-from-mssql-using-csharp/
Mods - let me know if something like this should be copy/pasted into the answer as the original URL may not be persistent.
Edit: Here is the code from the link in case the URL goes away:
Usage:
The code:
It appears Entity Framework doesn't support streaming the data to a varbinary field.
You have a couple of options.
Edit: Assuming you're using .NET 4.5, you should use
SqlDataReader.GetStream
. This will allow streaming the file without having to load the whole thing into memory.Try to load the Data with EF "AsNoTracking()" option!
Sample: MyContext.MyTable.AsNoTracking().Where( x => x.....)