tags:

views:

76

answers:

2

Is there a way to get the whole count when using the Take operator?

+3  A: 

The easiest way would be to just do a Count of the query, and then do Take:

var q = ...;
var count = q.Count();
var result = q.Take(...);
Stephen Cleary
+6  A: 

You can do both.

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

Just execute the count before the take. this will cause the query to be executed twice, but i believe that that is unavoidable.

if this is in a Linq2SQL context, as your comment implies then this will in fact query the database twice. As far as lazy loading goes though it will depend on how the result of the query is actually used.

For example: if you have two tables say Product and ProductVersion where each Product has multiple ProductVersions associated via a foreign key.

if this is your query:

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

where you are just selecting Products but after executing the query:

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

if you reference any foreign key or related object that was not part of the original query then it will be lazy loaded in. In your case, the count will not cause any lazy loading because it is simply returning an int. but depending on what you actually do with the result of the Take() you may or may not have Lazy loading occur. Sometimes it can be difficult to tell if you have LazyLoading ocurring, to check you should log your queries using the DataContext.Log property.

luke
if you use deferred loading does it still execute twice. I am still unsure about how exactly deferred loading works.
Kieran
@Kieran are you doing linq2sql? or linq to objects or something else?
luke