Загрузка данных из множества связанных таблиц в одном представлении asp.net - PullRequest
0 голосов
/ 28 февраля 2020

Я новичок в asp. net и, возможно, упускаю какое-то простое решение. В общем, у меня есть две таблицы Mov ie и Актер Вот их модели:

public class Movie
{
    public Movie()
    {
        this.Actors = new HashSet<Actor>();
    }
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public string Genre { get; set; }
    [Required]
    public DateTime ReleaseDate { get; set; }
    [Required]
    public DateTime AddDate { get; set; }
    public virtual ICollection<Actor> Actors { get; set; }

}

public class Actor
{
    public Actor()
    {
        this.Movies = new HashSet<Movie>();
    }
    public int id { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Movie> Movies { get; set; }
    public DateTime BirthDate { get; set; }
}

Я пытаюсь загрузить MOV ie Подробности и список актеров из mov ie с использованием ViewModel:

public class MovieDetailsViewModel
{
    public Movie Movie { get; set; }
    public Actor Actor { get; set; }
}

И контроллер для него находится здесь:

 private ApplicationDbContext _context;
    public MoviesController()
    {
        _context = new ApplicationDbContext();
    }
    protected override void Dispose(bool disposing)
    {
        _context.Dispose();
    }

    public ActionResult Index() 
    {
        var movie = _context.Movies.ToList();
        return View(movie);
    }
    public ActionResult Details(int id)
    {
        var movie = _context.Movies.SingleOrDefault(m => m.Id == id);
        var actor = _context.Actors.SingleOrDefault(a => a.id == id);

        var viewModel = new MovieDetailsViewModel
        {
            Movie = movie,
            Actor = actor
        };


        if (movie == null)
            return HttpNotFound();
        return View(viewModel);
    }

Действие Подробности есть тот, который должен загружать данные, которые мне нужны. Вид выглядит примерно так:

@model Movie_Rentals.ViewModels.MovieDetailsViewModel
@{
ViewBag.Title = Model.Movie.Name;
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@Model.Movie.Name</h2>
<ul>
<li>Genre: @Model.Movie.Genre</li>
<li>Release date: @Model.Movie.ReleaseDate.ToShortDateString()</li>
<li>Add date: @Model.Movie.AddDate.ToShortDateString()</li>
<li>Actors:@Model.Movie.Actors</li>
</ul>

И он отображает Актеры: System.Collections.Generi c .HashSet`1 [Movie_Rentals.Models.Actor] , который, я полагаю, должен , но я не могу найти решение о том, как сделать так, чтобы отображался фактический список актеров. Кто-нибудь имеет какие-либо идеи по моей проблеме, я был бы признателен за любую помощь.

PS Я не являюсь носителем английского языка sh, поэтому извините, если мой английский sh плохо.

Ответы [ 3 ]

1 голос
/ 28 февраля 2020

по вашему мнению вы можете попробовать:

<li>Actors: @string.Join("," Model.Movie.Actors.Select(a => a.Name).ToList())</li>

Таким образом, вы покажете список имен актеров, связанных с mov ie, который вы добавили в вашу модель представления.

Но я бы предложил вам реорганизовать модель представления, включив в нее список имен актеров, чтобы вы убрали логи c из вида. После этого ваш взгляд должен выглядеть следующим образом:

public class MovieDetailsViewModel
{
    public Movie Movie { get; set; }
    public List<string> ActorsNames { get; set; }
}

В вашем контроллере вы должны сделать:

public ActionResult Details(int id)
{
    var movie = _context.Movies.SingleOrDefault(m => m.Id == id);

    var viewModel = new MovieDetailsViewModel
    {
        Movie = movie,
        ActorsNames = string.Join(",", movie.Actors.Select(a => a.Name).ToList())
    };

    if (movie == null)
        return HttpNotFound();
    return View(viewModel);
}

Как вы можете видеть, я удалил код, в котором вы получаете одного актера от актеров DbSet, потому что это не полезно. Действительно, вам нужен полный список всех актеров, которые появились в mov ie, которые вы получаете из Movies DbSet, а не просто актер с тем же идентификатором mov ie, для которого вы должны загрузить детали.

Кроме того, обязательно включите отложенную загрузку, чтобы получить коллекцию актеров, связанных с mov ie, в противном случае вы получите пустую коллекцию.

Дайте мне знать, если мои предложения будет полезно.

0 голосов
/ 28 февраля 2020

Чтобы поле «Актеры» отображалось, вы можете справиться с этим несколькими способами. Самым простым решением было бы добавить свойство, которое анализирует коллекцию Actors в строку. Вы также можете написать код непосредственно в представление для l oop для каждого актера в коллекции.

Пример:

public class Movie
{
    public Movie()
    {
        this.Actors = new HashSet<Actor>();
    }
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public string Genre { get; set; }
    [Required]
    public DateTime ReleaseDate { get; set; }
    [Required]
    public DateTime AddDate { get; set; }
    public virtual ICollection<Actor> Actors { get; set; }

    public string ActorsToString
    {
        get
        {
            string _resultSet = "";
            if (Actors != null && Actors.Count > 0)
            {
                foreach (Actor _actor in Actors)
                {
                    _resultSet += $"{_actor.Name}, ";
                }
            }
            return _resultSet;
        }
    }
}
0 голосов
/ 28 февраля 2020

Вам необходимо загрузить Mov ie со всеми актерами, используя

_context.Movies.Include(x => x.Actors).SingleOrDefault(m => m.Id == id);

Затем в представлении

@foreach (var x in Model.Movie.Actors)
    {<li>x.Name</li>}
...