2009-09-01 4 views
27

Я хочу отфильтровать мои результаты, чтобы взять только Х количество записей. Мне интересно, как работает Take()?Linq Take() question

На этом сайте я нашел: http://www.hookedonlinq.com/TakeOperator.ashx

Это говорит Take() «Выдает ArgumentNullException если источник является недействительным.» И что же мне делать? Я не могу гарантировать, что каждый раз, когда я делаю Take(), у меня будет несколько записей в этой таблице или нет.

Так что мне сначала нужно сделать подсчет? Затем выполните другой запрос, чтобы убедиться, что есть некоторые записи для захвата?

Также, что произойдет, если у меня есть Take (2), но только в 1 записи, то это будет исключение?

ответ

42

Существует разница между пустой ссылкой и пустой коллекцией. Это нормально, чтобы позвонить в пустую коллекцию. И аргумент указывает максимальное число, которое нужно взять, поэтому также следует указать больше, чем есть элементы в коллекции.

Я рекомендую обратиться к MSDN для получения точных данных.

Для Linq к объектам: http://msdn.microsoft.com/en-us/library/bb503062.aspx

Для Ссылка на базы данных: http://msdn.microsoft.com/en-us/library/bb300906.aspx

+0

Есть прочь сделать это принять все результаты или ограничить количество результатов? Как только в зависимости от определенных условий я хочу ограничить количество результатов или мне придется разделить это отдельно (т.е. на разные методы)? – chobo2

+1

@ chobo2: Это именно то, что он делает уже. Если вы попросите 5 предметов, но у вас есть только 3, это даст вам все 3. –

9

Это пустая ссылка исключение только если вы делаете что против источника объекта, такие как:

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

Когда вы делаете Linq to SQL, он вернет EMPTY-перечислитель ваших данных, а не пустую ссылку. Точно так же, если вы пытаетесь взять больше, чем доступно, он будет использовать только доступную сумму. Я использую этот метод для отображения данных в некоторых случаях и, безусловно, много времени, когда я попрошу больше записей, чем список доступен.

+0

Вызов любого метода в 'null' будет вызывать исключение NullReferenceException. ArgumentNullException будет выведено, если вы вызовете Take как статический метод: 'List list = null; Enumerable.Take (list, 5); ' – knittl

2

Возьмите за исключение, если объект, вызывающий его, равен нулю. Скорее всего, у вас не будет нулевого объекта, а отсутствие или меньше строк - это не одно и то же (я уверен, вы понимаете семантику).

Если вы используете Linq в контекст SQL и запросах в моде

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

в случае Where возвращающихся нулевых результатов, вы не получите нулевое исключение, потому что ваш запрос не имеет еще был выполнен, тогда в случае, если он содержит только 1 результат, вы получите только один результат. Take ограничивает количество возвратов записей.

+0

" в случае возвращаемых нулевых результатов, вы не получите нулевое исключение, потому что ваш запрос еще не выполнен "- Нет.Вы не получите null-исключение, потому что если 'Where' не возвращает никаких результатов, он возвращает ненулевую ссылку на объект, представляющий пустую последовательность. –

0

Подсчитать количество элементов, прежде чем принять():

List<string> a = new List<string>(); 
      int count = a.Count > 12 ? 12 : a.Count; 
      a.Take(count); 
+0

Это не нужно. Из [документации] (https://msdn.microsoft.com/en-us/library/bb503062 (v = vs.110) .aspx): «Принимать ' перечисляет 'source' и дает элементы до' count' элементы 'или' source' не содержат больше элементов. Если 'count' превышает количество элементов в' source', возвращаются все элементы 'source'. –