I am using Linq to Sql. Here is the code:
Dictionary<string, int> allResults;
using (var dc= new MyDataContext())
{
dc.CommandTimeout = 0;
allResults = dc.MyTable.ToDictionary(x => x.Text, x => x.Id);
}
it is ran on a 64 bit machine and the compilation is AnyCPU. It throws a System.OutOfMemoryException.
This accesses an SQL Server database. The Id field maps to an SQL Server int field, And the Text field maps to Text(nvarchar(max)) field. Running select COUNT(*) from TableName
results in 1,173,623 records and running select sum(len(Text)) from TableName
results in 48,915,031. Since int is a 32 bit integer, the ids should take only 4.69MB of space and the strings less than 1GB. So we are not even bumping against the 2GB/object limit.
I then change the code in this way:
Dictionary<string, int> allResults;
using (var dc = new MyDataContext())
{
Dictionary<string, int> threeHundred;
dc.CommandTimeout = 0;
var tot = dc.MyTable.Count();
allResults = new Dictionary<string, int>(tot);
int skip = 0;
int takeThis = 300000;
while (skip < tot)
{
threeHundred = dc.MyTable.Skip(skip).Take(takeThis).ToDictionary(x => x.Text, x => x.Id);
skip = skip + takeThis;
allResults = allResults.Concat(threeHundred).ToDictionary(x => x.Key, x => x.Value);
threeHundred = null;
GC.Collect();
}
}
I learn that garbage collaction here does not help and that the out of memory exception is thrown on the first line in the while loop once skip = 900,000.
What is wrong and how do I fix this?