35

I want to filter my results to take only the X amount of records. I am wondering how does Take() work?

On this site I found: http://www.hookedonlinq.com/TakeOperator.ashx

It says Take() "Throws an ArgumentNullException if source is null." So what should I do? I can't guarantee that everytime I do a Take() I will have some records in that table or not.

So do I first have to do a count? Then do another query to make sure there is some records to grab?

Also what happens if the I have a Take(2) but only 1 record will it throw this same exception?

d219
  • 2,707
  • 5
  • 31
  • 36
chobo2
  • 83,322
  • 195
  • 530
  • 832

4 Answers4

63

There's a difference between a null reference and an empty collection. It's fine to call Take on an empty collection. And the argument specifies a maximum number to take, so it's also fine to specify more than there are items in the collection.

I recommend referring to MSDN for precise details like this.

For Linq to Objects: http://msdn.microsoft.com/en-us/library/bb503062.aspx

For Link to databases: http://msdn.microsoft.com/en-us/library/bb300906.aspx

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
  • Is there away to make it take all results or limit the number of results? Like only depending on certain conditions I want to limit the number of results or will I have to split this apart(ie to different methods)? – chobo2 Sep 01 '09 at 19:12
  • 1
    @chobo2: That's exactly what it does already. If you ask for 5 items but it only has 3, it will give you all 3. – Jon Skeet Sep 01 '09 at 19:38
14

That null reference exception is only if you are doing that against an object source such as:

List<MyObject> myList = null;
myList.Take(5); // this would produce the error, of course

When you are doing Linq to SQL it'll return an EMPTY enumerator of your data, not a null reference. On the same token, if you are attempting to take more than is available it'll only take up the amount available. I use this method to page data in some instances and definitely a lot of the time when I'll ask for more records than the list has available.

Fooberichu
  • 428
  • 1
  • 5
  • 13
  • 1
    Calling any method on `null` is going to throw a NullReferenceException. ArgumentNullException will be thrown if you invoke Take as a static method: `List list = null; Enumerable.Take(list, 5);` – knittl Jul 29 '13 at 14:22
2

Take will through an exception if the object invoking it is null. Chances are you will not have a null object, and having no or less rows is not the same (I am sure you understand the semantics).

If you are using a Linq to SQL context and querying in the fashion of

Context.MyTable.Where(x => x.ID > 0).Take(2);  

in the case of the Where returning zero results, you will not get a null exception, because your query has not yet been executed, then in the case of it only containing 1 result, you will end up only getting 1 result back. Take limits the amount of records returns.

Quintin Robinson
  • 81,193
  • 14
  • 123
  • 132
  • 1
    "in the case of the Where returning zero results, you will not get a null exception, because your query has not yet been executed" - No. You will not get a null exception because if `Where` returns no results, it returns a non-null reference to an object representing an empty sequence. – Daniel Earwicker Sep 01 '09 at 19:01
0

Count the number of items before you Take():

List<string> a = new List<string>();
            int count = a.Count > 12 ? 12 : a.Count;
            a.Take(count);
kmehta
  • 2,457
  • 6
  • 31
  • 37
  • 5
    This is unnecessary. From the [documentation](https://msdn.microsoft.com/en-us/library/bb503062(v=vs.110).aspx): "`Take` enumerates `source` and yields elements until `count` elements have been yielded or `source` contains no more elements. If `count` exceeds the number of elements in `source`, all elements of `source` are returned." – Nicholas Flees Sep 21 '16 at 21:16