2009-12-16 2 views
2

많은 LINQ to SQL은 테이블에서 데이터를 읽은 다음 ToList() 확장 메서드를 호출하고 메모리의 데이터를 사용합니다. 그러나 이제 LINQ to SQL을 사용하여 메모리에 저장할 수있는 레코드를 더 많이 처리하려고합니다.메모리에 너무 많은 레코드가있는 LINQ to SQL

int skip = 0; 
IList<Record> records = new List<Record>(); 
do 
{ 
    records = DBRecords.Skip(skip).Take(1000).Select(a => new Record 
    { 
     // Set values here... 
    }).ToList(); 
    foreach (Record r in records) 
    { 
     yield return r; 
    } 
    skip += 1000; 
} while (records.Count > 0); 

이 날 한 번에 1000 개 개의 레코드를 가져 앱에 일괄 적으로 그들을 반환 할 수 있습니다 : 이것은 내가 지금까지 가지고 올 한 패턴이다. 그러나, 나는 이것을하는 더 좋은 방법이 있어야한다는 것을 안다?

+0

나는 특히 더 좋은 방법이 있는지 모르겠다. 그러나 데이터베이스에 대한 모든 여행에 비용이 들기 때문에, 한 번에 얼마나 많은 레코드를 가져 가는지 분석해야한다. 행을 어떻게 보이는지 게시하지 않았으므로 정확하게 말할 수는 없지만 기계 메모리를 채우는 데 1000 행 정도가 들리지는 않습니다. –

답변

2

linq는 지연 평가되지만 ToList()는 전체 결과를 인식합니다. 아마도 ToList()를 삭제하고 쿼리 결과를 직접 반환 할 수 있습니다. foreach 블록에서 호출자의 결과를 처리하는 것은 그렇게 지연됩니다.

2

스트리밍 방식으로 한 번에 하나씩 레코드를 처리 할 수없는 이유는 무엇입니까?

foreach (Record record in query) 
{ 
    // Do stuff... 
} 

또한 어떤 계산을 수행하고 있습니까? 데이터베이스를 통해 계산을 수행하고 결과를 알려주는 것이 가능한지 고려해 보셨습니까? 이것은 귀하의 상황에서 가능하지 않을 수도 있지만, 그렇다면 훨씬 빠를 것입니다.

2

왜 목록으로 변환해야합니까? LINQ의 핵심은 반환 된 IEnumerable을 열거하면서 데이터를 반환하도록하는 것입니다. 데이터베이스에서 한 번에 몇 개의 레코드를 내부적으로 읽어야합니다.

2

그냥 IEnumerable을 반환하려고하는 것처럼 DBRecords를 반환 할 수 있습니다. 어쨌든 느리게 평가됩니다. 이 작업을 수행하는 경우 조심해야 할 것은 데이터베이스 액세스가 실제로 IEnumerable 평가를 시작할 때까지 시작되지 않는다는 것입니다. 상황에 따라 예외 처리가 약간 복잡해질 수 있습니다.