在一个视图 asp.net 中从多到多相关表中加载数据

Posted

技术标签:

【中文标题】在一个视图 asp.net 中从多到多相关表中加载数据【英文标题】:Load data from many to many related tables in one view asp.net 【发布时间】:2020-02-27 22:53:24 【问题描述】:

我是 asp.net 的新手,可能缺少一些简单的解决方案。所以基本上我有两张表 MovieActor 这是他们的模型:

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; 

我正在尝试使用 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);
    

Action Details 是需要加载我需要的数据的操作。 视图看起来像这样:

@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>

它显示 Actors:System.Collections.Generic.HashSet`1[Movie_Rentals.Models.Actor] 我想它应该显示,但我无法找到如何解决使其显示实际的演员列表。有没有人对我的问题有任何想法,我将不胜感激。

附注我不是以英语为母语的人,如果我的英语不好,请见谅。

【问题讨论】:

【参考方案1】:

在您看来,您可以尝试:

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

这样,您将显示与您添加到视图模型的电影相关联的演员姓名列表。

但我建议您重构视图模型以包含演员姓名列表,这样您就可以从视图中删除逻辑。之后,您的视图应如下所示:

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);

如您所见,我已经删除了您从 Actors DbSet 中获取单个演员的代码,因为它没有用。实际上,您需要从 Movies DbSet 获得的电影中出现的所有演员的完整列表,而不仅仅是一个与您必须加载其详细信息的电影具有相同 id 的演员。

另外,请确保已激活延迟加载以获取与电影关联的演员集合,否则,您将获得一个空集合。

让我知道我的建议是否有用。

【讨论】:

【参考方案2】:

您需要使用所有 Actor 加载电影

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

然后在视图中

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

【讨论】:

非常感谢,我希望我早点使用***,它可以为我节省很多时间!【参考方案3】:

要允许显示 Actors 字段,您可以通过几种方式处理此问题。最简单的解决方案是添加一个将 Actors 集合解析为字符串的属性。你也可以直接在 View 中编写代码来遍历集合中的每个actor。

例子:

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;
        
    

【讨论】:

我建议不要将您的显示逻辑(UI 层)放在 DB 模型(数据访问层)中。

以上是关于在一个视图 asp.net 中从多到多相关表中加载数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 asp.net core mvc 在引导模式中加载 AngularJS 代码

在 C# asp.net 中加载 XSLT 时出错

在 ASP.NET Core PartialView 中加载脚本后渲染脚本部分

如何使用 ASP.NET 从个人存储中加载客户端证书?

在 ASP.NET Core 应用程序中加载自定义 ConfigSection

防止在 Asp.Net Core ViewComponents 中加载多个 JavaScript 脚本