2016-07-28 3 views
0

현재 3 백만 -4 백만 행의 aprox를 포함하는 compact ce 데이터베이스에서 큰 테이블을 읽으려고합니다. 데이터베이스 크기는 현재 832MB입니다. 기록과 목록을 채우기 이C# DbDataReader가 List 결과를 OutOfMemoryException으로 채우는 중

모형 코드를 OutOfMemoryException을 던지고있다 :

using (var con = new DomainContext()) 
    { 
     foreach (var item in con.logRecords) 
     { 
      if (item.Info != null && item.Info != "") 
       item.Timestamp = DateTime.ParseExact(item.Info, "MM.dd.yyyy HH:mm:ss.fff", culture).Ticks; 
     } 
     con.SaveChanges(); 

    } 

새로운 접근 방식, 여전히 일을 못하고 ....

내가 네이티브 SQL을 사용
 Task.Factory.StartNew(() => 
     { 
      using (var con = new DomainContext()) 
      { 
       for (int i = 0; i < 300; i++) 
       { 
        try 
        { 
         var temp = con.logRecords.Where(p => p.Id <= i * 10000 + 10000 && p.Id >= i * 10000); 

         foreach (var item in temp) 
         { 

          if (item.Info != null && item.Info != "") 
           item.Timestamp = DateTime.ParseExact(item.Info, "MM.dd.yyyy HH:mm:ss.fff", culture).Ticks; 
         } 

         con.SaveChanges(); 

        } 
        catch { } 
        GC.Collect(); 
        Console.WriteLine(i.ToString()); 


       } 
      } 
     }); 
+2

두 번째 코드에서 항상 동일한 문자열 리터럴을 사용하고 있기 때문입니다. 이것은 .NET 문자열 풀에 포함되지 않습니다. 'new String ("WGwegWEGwegWEGwegWEGwegWEGweg".ToCharArray())'를 사용하면 생성자를 통해 초기화 된 문자열이 인턴드되지 않기 때문에 동일한 예외가 발생합니다. –

+0

아, 맞아! 감사! 나는 대량으로 이것을하는 방법을 알아 내야 만한다고 생각한다. ... – Snovva1

+1

최선의 최적화는 레코드 그룹을 메모리에로드하지 않고 (데이터베이스 페이징에 의해) 또는 레코드를 생략함으로써 (WHERE ...를 사용하여) '). –

답변

0

, 파싱 ​​된 타임 스탬프를 SQL 타임 스탬프로 변환 한 다음 1970 년부터 DATEDIFF (datepart, startdate, enddate)를 사용하여 초 단위로 숫자를 찾습니다. 0 년 이래로 초를 추가했습니다. 밀리 초의 부분을 잃어 버렸지 만, 이것이 가장 좋은 일이라고 생각합니다.