2010-05-18 2 views
2

Take 연산자를 사용할 때 전체 카운트를 얻는 방법이 있습니까?LINQ가있는 테이크와 함께 카운트 사용

+0

IQueryable<Person> yourQuery = People .Where(x => /* complicated query .. */); 

당신은 여기에 다음과 같은 추가 할 수 있습니다 :이 경우

는 쿼리입니다 질문은 특별히 linq2sql에 대한 질문입니다. – luke

답변

6

당신은 둘 다 할 수 있습니다.

IEnumerable<T> query = ...complicated query; 
int c = query.Count(); 
query = query.Take(n); 

테이크 전에 카운트를 실행하기 만하면됩니다. 이 쿼리를 두 번 실행하게됩니다,하지만 그건 불가피합니다 믿습니다.

이것이 Linq2SQL 컨텍스트에있는 경우 주석에서 암시 하듯이 실제로 데이터베이스에 두 번 쿼리합니다. 게으른 로딩은 비록 쿼리의 결과가 실제로 어떻게 사용되는지에 달려 있습니다.

예를 들어

: 당신이있는 경우 두 테이블은 ProductProduct는 외래 키를 통해 관련된 여러 ProductVersions있다 ProductVersion 말한다.

이 쿼리 인 경우 : 당신은 그냥 Products을 선택하지만 쿼리를 실행 한 후 있습니다

var query = db.Products.Where(p => complicated condition).OrderBy(p => p.Name).ThenBy(...).Select(p => p); 

:

var results = query.ToList();//forces query execution 
results[0].ProductVersions;//<-- Lazy loading occurs 

당신의 부분이 아니었던 외국 키 또는 관련 객체를 참조하는 경우 원래 질의가 지연되면서로드됩니다. 단순히 int를 반환하기 때문에 카운트가 지연로드를 발생시키지 않습니다. Take()의 결과로 실제로 무엇을하는지에 따라 지연로드가 발생할 수도 있고 그렇지 않을 수도 있습니다. 때때로 LazyLoading이 있는지 여부를 알기가 어려우면 DataContext.Log 속성을 사용하여 쿼리를 기록해야하는지 확인하십시오.

+0

지연된로드를 사용하는 경우에도 여전히 두 번 실행됩니다. 지연로드가 정확히 작동하는지에 대해서는 여전히 확신 할 수 없습니다. – Kieran

+0

@Kieran linq2sql을 (를)하고 있습니까? 또는 linq 개체 또는 다른 뭔가? – luke

4

가장 쉬운 방법은 쿼리의 Count을 할 수 있으며, 다음 Take 할 것 :

var q = ...; 
var count = q.Count(); 
var result = q.Take(...); 
2

단일 Linq-to-SQL 쿼리 (하나의 SQL 문만 실행)에서이 작업을 수행 할 수 있습니다. 생성 된 SQL은 으로 보이지만, 불쾌한 결과가 될 수도 있습니다. 드릴 것입니다

var result = yourQuery 
    .GroupBy (x => true) // This will match all of the rows from your query .. 
    .Select (g => new { 
     // .. so 'g', the group, will then contain all of the rows from your query. 
     CountAll = g.Count(), 
     TakeFive = g.Take(5), 
     // We could also query for a max value. 
     MaxAgeFromAll = g.Max(x => x.PersonAge) 
    }) 
    .FirstOrDefault(); 

당신과 같이 데이터에 액세스 :이 경우

// Check that result is not null before access. 
// If there are no records to find, then 'result' will return null (because of the grouping) 
if(result != null) { 

    var count = result.CountAll; 

    var firstFiveRows = result.TakeFive; 

    var maxPersonAge = result.MaxAgeFromAll; 

}