Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally adding .Take()

Tags:

linq

c#-4.0

Currently I have this that automatically takes 500 rows:

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate).Take(500);

I'd like to make the Take() conditional, something like this:

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate);
if (condition)
    orderQuery = orderQuery.Take(500);

Is this possible?

Edit:
The compiler says

"Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Linq.IOrderedQueryable'."

like image 527
chrismat Avatar asked Apr 24 '13 21:04

chrismat


2 Answers

Add "AsQueryable" to make the types line up:

var orderQuery = subsetTable.Where(pred).OrderByDescending(o => o.CreationDate).AsQueryable();
if (condition)
    orderQuery = orderQuery.Take(500);
like image 96
Tormod Avatar answered Sep 17 '22 12:09

Tormod


In Linq-to-Objects, the var will infer to IOrderedEnumerable<T>, where T is the type of your object. The Take() will yield an IEnumerable<T>, so your line of code there will not be allowed. (IOrderedEnumerable is more specified than IEnumerable, you need your query to typed in a less-specified manner.) And, as the comments point out, the same holds true for providers that deal in terms of IQueryable<T>, which itself can be expressed as a less specified IEnumerable<T>.

To make it work, explicitly type your query to the lesser specified type you need, IEnumerable<T> or IQueryable<T>, and then you can apply your conditional Take.

IEnumerable<YourType> orderedQuery = ...
if (condition)
     orderedQuery = orderedQuery.Take(n);
like image 39
Anthony Pegram Avatar answered Sep 18 '22 12:09

Anthony Pegram