Попытка получить первый элемент в коллекции возвращает NULL - PullRequest
3 голосов
/ 02 марта 2012

Ранее я много занимался разработкой с использованием Stored Procs для всех модификаций данных.

Но теперь мне нужно использовать LINQ To SQL, и основная фундаментальная задача поставила меня в тупик.

У меня есть класс с именем Book (название, автор и т. Д.). Ряд книг создаются и добавляются в общедоступные книги коллекций ObservableCollection

Пока все хорошо, я вижу, что в его коллекции есть действительные книги.

У меня есть функция DeleteOldestBook () , которая просто получает первую Книгу в Книгах и удаляет. Здесь я сталкиваюсь с неприятностями.

Я пытаюсь выбрать

Book BookToDelete = Books.Take(1) as Book;

но всегда возвращает NULL.

Мне удалось взломать обходной путь:

var AllBooks = from BookToDelete in Books select BookToDelete;
foreach (Book BookToDelete in AllBooks)
{ 
    //  BookToDelete.dostuff takes place ... 
    break; // only do 1
}

Но это ужасно, и я знаю, что я упустил кое-что простое.

Есть идеи от экспертов LINQ? Дайте мне знать, если вам нужно больше кода.

Заранее спасибо

Ответы [ 6 ]

10 голосов
/ 02 марта 2012

Take() возвращает IEnumerable<Book>. Таким образом, ваша попытка преобразовать его в Book не удалась, возвращая нулевое значение.

Используйте Books.First() или Books.FirstOrDefault() вместо.

Разъяснение для Nitpickers : Take() может фактически вернуть IQuerable<Book>, если Books пришло непосредственно от DataContext.

6 голосов
/ 02 марта 2012

просто используйте FirstOrDefault():

var firstBook = Books.FirstOrDefault();

Если в коллекции нет книг, firstBook будет null, в противном случае будет установлено первоевещь.

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

var firstThriller = Books.Where(b => b.Type == "Thriller")
                         .FirstOrDefault();
6 голосов
/ 02 марта 2012

Take вернет коллекцию с n элементами.Вам все еще нужно перебрать эту коллекцию.В вашем случае размер коллекции 1. 1. 1004 *

First вернет первый элемент коллекции.

Дополнительный кредит

Если ваша коллекция еще не отсортирована, используйте OrderBy

Book bookToDelete = Books.OrderBy(b => b.SomeDate).First();
3 голосов
/ 02 марта 2012

Я бы просто использовал

Books.First();

вместо

Take(1);

Метод Take Extension возвращает IQueryable<T>, и вы пытаетесь привести к T (Book).Вот почему вы всегда получаете ноль.

2 голосов
/ 02 марта 2012

Да, вы пропустили метод расширения First():

Book BookToDelete = Books.First();

Обратите внимание, что Take(int) возвращает последовательность книг (IQueryable<T>) - даже если эта последовательность содержит только один элемент в вашем случае,Поскольку нет преобразования из IQueryable<T> в T, as вернет ноль.

1 голос
/ 02 марта 2012

Take возвращает IEnumerable<T>, содержащий один элемент, который вы хотите:

Books.FirstOrDefault();

Возвращает первый элемент (или null, если Books пусто).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...