Как перевести IQueryable в список пользовательских классов? - PullRequest
0 голосов
/ 26 января 2020

Этот вопрос основан на dotnet@2.1 MVC приложении.

У меня есть следующая функция, которая должна возвращать Список некоторого класса, который я создал. Кто-нибудь знает, как я могу перевести IQueryable в список? Я пробовал ToList (). Но это все равно дает мне ошибку преобразования.

Невозможно неявно преобразовать тип 'System.Collections.Generi c .List <>' в 'Model.Book []' [firstChance-2nd-попытки ] csharp (CS0029)

LibraryController.cs

        [HttpGet("GetAuthorsAndBooks")]
        public AuthorBooks[] GetAuthorsAndBooks()
        {
            //TODO 6: missing code 1pt
            var authorsAndBooks = (
              from a in _context.Authors
              let bookList = (
                from ba in _context.BookAuthor
                where ba.AuthorId == a.Id
                join b in _context.Books on ba.BookId equals b.Id
                select new { Id = b.Id, Title = b.Title, Year = b.Year }
              )
              select new AuthorBooks { Author = a, Books = bookList.ToList() }
            );

            return authorsAndBooks; // ! CONVERT ERROR
        }
        public class AuthorBooks
        {
            public Author Author { get; set; }
            public Book[] Books { get; set; }
        }

Благодаря @Phong все работает. См. Ниже LibraryController.cs .

LibraryController.cs [решение]

        [HttpGet("GetAuthorsAndBooks")]
        public AuthorBooks[] GetAuthorsAndBooks()
        {
            //TODO 6: missing code 1pt
            var authorsAndBooks = (
              from a in _context.Authors
              let bookList = (
                from ba in _context.BookAuthor
                where ba.AuthorId == a.Id
                join b in _context.Books on ba.BookId equals b.Id
                select new Book { Id = b.Id, Title = b.Title, Year = b.Year }
              )
              select new AuthorBooks { Author = a, Books = bookList.ToArray() }
            ).ToArray();

            return authorsAndBooks;
        }
        public class AuthorBooks
        {
            public Author Author { get; set; }
            public Book[] Books { get; set; }
        }

Ответы [ 2 ]

1 голос
/ 26 января 2020

У вас есть 2 способа избавиться от ошибки

  • Объявить List вместо Array введите

    public class AuthorBooks
    {
        public Author Author { get; set; }
        public List<Book> Books { get; set; }
    }
    
  • Books = bookList.ToArray() вместо.

Обновлено

Вы выбираете anonymous type здесь

select new { Id = b.Id, Title = b.Title, Year = b.Year }

Так что вы должны вместо этого выберите new Book, как этот

select new Book { Id = b.Id, Title = b.Title, Year = b.Year }
0 голосов
/ 26 января 2020

Интерфейс IQueryable<AuthorBooks> отличается от List<AuthorBooks>. Первая проблема заключается в том, что ваш метод возвращает тип AuthorBooks[], который также отличается от желаемого типа возврата List<AuthorBooks>.

Если вы sh метод GetAuthorsAndBooks() вернете List<AuthorBooks>, сначала соответствующим образом измените его тип возврата.

Затем в коде ваш оператор return в настоящее время возвращает переменная authorsAndBooks. Назначение этой переменной происходит через запрос LINQ, который приводит к типу IQueryable<AuthorBooks>. Интерфейс IQueryable<T> реализует интерфейс IEnumerable<T>. Эти интерфейсы предназначены для преобразования практически любого IQueryable<T> или IEnumerable<T> во многие другие типы коллекций. Одним из таких методов является преобразование в List<T>. И это доступно через метод ToList(). (Обратите внимание, что если по какой-то причине вы по-прежнему хотите сохранить существующий тип возврата как AuthorBooks[], вы можете преобразовать в массив вместо List, используя метод ToArray() вместо ToList().)

Обратите внимание, что вам нужно импортировать System.Linq в свой код, чтобы иметь возможность использовать эти методы, если вы еще этого не сделали.

Определение IQueryable<T> (см., Что он реализует IEnumerable<T> :

https://docs.microsoft.com/en-us/dotnet/api/system.linq.iqueryable-1?view=netframework-4.8#definition

Определение метода ToList() доступно в IEnumerable<T>:

https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tolist?view=netframework-4.8

ПРИМЕЧАНИЕ. Технически интерфейс IEnumerable<T> сам по себе не реализует метод ToList() и даже не является частью реального интерфейса. Вместо этого он фактически определен для класса c класса Enumerable используя "методы расширения".

ПРИЛОЖЕНИЕ: Для дополнительного удовольствия вы можете посмотреть исходный код самого метода ToList() в. NET Framework здесь:

https://github.com/microsoft/referencesource/blob/master/System.Core/System/Linq/Enumerable.cs

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