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?