Выберите Tag Helper для отображения 2 полей в выпадающем списке - PullRequest
0 голосов
/ 11 апреля 2019

При использовании стандартных скаффолдингов индексы отображаются только в выпадающих списках связанных таблиц. Как отобразить несколько полей, чтобы выпадающий список имел смысл?

Я попытался использовать решение, описанное Shyju в разделе «Получение данных из вашей таблицы базы данных с использованием структуры сущностей». ( Выберите Tag Helper в ASP.NET Core MVC ).

У меня есть 2 класса в модели (Книги с соответствующим автором):

namespace SimpleAppwithTwoTables.Data
{
    public class Book
    {
        public int BookID { get; set; }
        [StringLength(255)]
        [Display(Name ="Book Title")]
        public string Title { get; set; }
        public int AuthorID { get; set; }
        public Author Author { get; set; }
     }
}

и

namespace SimpleAppwithTwoTables.Data
{
    public class Author
    {
        public int AuthorID { get; set; }
        [Display(Name = "First Name")]
        [StringLength(50)]
        public string FirstName { get; set; }
        [Display(Name = "Last Name")]
        [StringLength(50)]
        public string LastName { get; set; }
        public ICollection<Book> Books { get; set; } = new List<Book>();
    }
}

В BooksController есть метод Create (), похожий на тот, который был описан в посте Shyju.

 public IActionResult Create()
            Author vm = new Author();
            vm.Books = _context.Book.Select(a => new SelectListItem()
            { Value = a.AuthorID.ToString(), Text = a.Author.LastName }).ToList();
            return View(vm);
        }

Эта строка в контроллере

 vm.Books = _context.Book.Select(a => new SelectListItem()
            { Value = a.AuthorID.ToString(), Text = a.Author.LastName }).ToList();

Генерирует эту ошибку:

"Невозможно неявно преобразовать тип 'System.Collections.Generic.List ' в 'System.Collections.Generic.ICollection '. Существует явное преобразование (вам не хватает приведения?).

Обратите внимание, что я новичок в C # и понимаю, что это проблема преобразования типов и что строка с ошибкой предполагает, что модель Author содержит ICollection <>.

Я ищу код, необходимый в строке vm.books, который не выполняет преобразование типов и работает с ICollection.

Ответы [ 2 ]

1 голос
/ 11 апреля 2019

Вы пытаетесь вставить список SelectListItem в свойство, определенное как список Book.SelectListItem совершенно очевидно, что это не то же самое, что Book, поэтому он терпит неудачу.

Простое решение состоит в том, что вам нужно свойство в вашей модели представления, специально предназначенное для хранения параметров списка выбора:

public IEnumerable<SelectListItem> AuthorOptions { get; set; }

Вам также понадобится что-то, чтобы связать выбранные элементы, которые будут примитивными типами, а не фактическими Author экземплярами:

public List<int> SelectedAuthorIds { get; set; }

По вашему мнению, тогда:

<select asp-for="SelectedAuthorIds" asp-items="AuthorOptions">

На посту вам нужно будет использовать эту коллекцию идентификаторов для запросов к фактическим объектам автора, если вам нужно связать их с книгой или чем-то еще:

var selectAuthors = await _context.Authors.Where(x => vm.SelectedAuthorIds.Contains(x.Id)).ToListAsync();
0 голосов
/ 13 апреля 2019

Я последовал совету Криса Пратта, приведенному выше.Потребовалось время, чтобы понять, но почти с работой.Подробности см. Ниже.

См. Модель для книги и автора выше.

Создан новый ViewModel:

namespace SimpleDropDownList.Models
{
    [NotMapped]
    public class AuthorViewModel
    {
        //Property to hold the list of authors in the GET
        public IEnumerable<SelectListItem> AuthorOptions { get; set; }

        //Property to bind the selected author used in the POST
        public List<int> SelectedAuthorIds { get; set; }
    }
}

Изменен метод Create () в BooksController для:

 public IActionResult Create()
        {
            //ViewData["AuthorID"] = new SelectList(_context.Set<Author>(), "AuthorID", "AuthorID");
            AuthorViewModel vm = new AuthorViewModel();
            vm.AuthorOptions = _context.Book.Select(x => new SelectListItem()
            { Value = x.AuthorID.ToString(), Text = x.Author.LastName }).ToList();
        return View(vm);
        }

Измените представление "Создать" на:

@model SimpleDropDownList.Models.Book

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Book</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Title" class="control-label"></label>
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="AuthorID" class="control-label"></label>
                @*<select asp-for="AuthorID" class ="form-control" asp-items="ViewBag.AuthorID"></select>*@

                <select asp-for="@Model.AuthorViewModel.SelectedAuthorIds" asp-items="@Model.AuthorViewModel.AuthorOptions"></select>
                
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Model: AuthorViewModel

Когда я запускаю это и нажимаю кнопку Создать, генерируется следующая ошибка:

Произошло необработанное исключение при обработке запроса.InvalidOperationException: элемент модели, передаваемый в ViewDataDictionary, имеет тип 'SimpleDropDownList.Models.AuthorViewModel', но для этого экземпляра ViewDataDictionary требуется элемент модели типа 'SimpleDropDownList.Models.Book'.

I'mпометить этот вопрос как завершенный и создать новый вопрос для проблемы, описанной чуть выше.См. Здесь: Ошибка при открытии страницы Razor и наличии соответствующего раскрывающегося списка

...