如何在 ASP.NET MVC 视图中将主键转换为实际名称/描述符字段

Posted

技术标签:

【中文标题】如何在 ASP.NET MVC 视图中将主键转换为实际名称/描述符字段【英文标题】:How in an ASP.NET MVC view do I convert primary keys to actual names / descriptor fields 【发布时间】:2021-08-08 23:30:32 【问题描述】:

我希望显示一个 ASP.NET MVC 视图以通过视图显示我的预订表数据。

但是,视图将 Movie 和 Venue 数据简单地输出为与其主键对应的 ID 值。当然,这对人类来说不是很可读。我已经尝试了大约 4 个小时来解决这个问题,而应该简单的却不是。我找不到将那个 ID 变成电影或场地名称的方法。感谢您提供任何帮助,这适用于几天后到期的一些课程。谢谢

我的观点标记:

@model IEnumerable<MovieClubSite.Controllers.Booking>

@
    ViewBag.Title = "Booking Manager";


<br />
<h2>Booking Manager</h2>

<ul class="list-group">
    <li class="list-group-item list-group-item-dark">Pick a showing</li>

    @foreach (var item in Model)
    
        <li class="list-group-item list-group-item-action list-group-item-info">
            <div class="float-left">
                <b>Username:</b> @html.DisplayFor(modelItem => item.CustomerReference)<br />
                <b>Movie:</b>@Html.DisplayFor(modelItem => item.Showing.MovieID)<br />
                <b>Venue:</b>@Html.DisplayFor(modelItem => item.Showing.VenueID)<br />
                <b>Date/Time:</b>@Html.DisplayFor(modelItem => item.Showing.ShowingDateTime)<br />
            </div>
            <div class="float-right">
                <a href='@Url.Action("Edit", "Bookings", new  id = item.BookingID )'><img src="~/Resources/pencil.png" style="width: 1.5rem"></a><br />
                <a href='@Url.Action("Delete", "Bookings", new  id = item.BookingID )'><img src="~/Resources/recycle-bin.png" style="width: 1.5rem"></a>
            </div>
        </li>

    
    <a href='@Url.Action("Create", "Bookings")' class="list-group-item list-group-item-action list-group-item-success">
        Add a new showing
    </a>
</ul>

我的 Booking 控制器的代码:

// GET: Bookings
public ActionResult Index()

    var bookings = db.Bookings
                     .Include(b => b.Member)
                     .Include(b => b.Showing);

    return View(bookings.ToList());

预订课程


namespace MovieClubSite.Controllers

    using System;
    using System.Collections.Generic;
    
    public partial class Booking
    
        public int BookingID  get; set; 
        public int ShowingID  get; set; 
        public int MemberID  get; set; 
        public string CustomerReference  get; set; 
    
        public virtual Member Member  get; set; 
        public virtual Showing Showing  get; set; 


    

电影课

namespace MovieClubSite.Controllers

    using System;
    using System.Collections.Generic;
    
    public partial class Movie
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Movie()
        
            this.Showings = new HashSet<Showing>();
        
    
        public int MovieID  get; set; 
        public string MovieName  get; set; 
        public Nullable<int> MovieYear  get; set; 
        public string MovieImage  get; set; 
        public string MovieDescription  get; set; 
        public string MovieLinkWiki  get; set; 
        public string MovieLinkIMDB  get; set; 
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Showing> Showings  get; set; 
    

显示类


namespace MovieClubSite.Controllers

    using System;
    using System.Collections.Generic;
    
    public partial class Showing
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Showing()
        
            this.Bookings = new HashSet<Booking>();
        
    
        public int ShowingID  get; set; 
        public int MovieID  get; set; 
        public int VenueID  get; set; 
        public System.DateTime ShowingDateTime  get; set; 
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Booking> Bookings  get; set; 
        public virtual Movie Movie  get; set; 
        public virtual Venue Venue  get; set; 
    

场地类


namespace MovieClubSite.Controllers

    using System;
    using System.Collections.Generic;
    
    public partial class Venue
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Venue()
        
            this.Showings = new HashSet<Showing>();
        
    
        public int VenueID  get; set; 
        public string VenueDescription  get; set; 
        public int VenueCapacity  get; set; 
        public string VenueName  get; set; 
        public string VenueImage  get; set; 
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Showing> Showings  get; set; 
    

【问题讨论】:

您至少需要发布 Showing、Movie 和 Venue 类 我可以从预订控制器的.Include(b =&gt; b.Showing) 部分获取显示类信息。我将如何发布电影和场地课程?如果您能对此提供任何帮助,我将不胜感激 为了创建视图模型,我们需要查看类之间的关系 好的,我已经将所有的类添加到上面的帖子和表格 EDMX 数据库关系的屏幕截图 【参考方案1】:

由于您已经在模型中包含导航属性,您只需更改显示的属性:

<b>Movie:</b>@Html.DisplayFor(modelItem => item.Showing.Name)<br />
<b>Venue:</b>@Html.DisplayFor(modelItem => item.Showing.Name)<br />

.Name 是保存值的实际属性,您要显示。

但是,作为一项规则,您永远不希望将整个实体传递到您的视图中。一个更好的做法是创建一个视图模型类并且只选择你需要的属性:

public class BookingViewModel

    public int BookingId  get; set; 
    public string CustomerReference  get; set; 
    public string Venue  get; set; 
    public string Movie  get; set; 
    public DateTime ShowingDateTime  get; set; 


// GET: Bookings
public ActionResult Index()

    var bookings = db.Bookings
                     .Include(b => b.Member)
                     .Include(b => b.Showing)
                         .ThenInclude(sh => sh.Movie)
                         .ThenInclude(sh => sh.Venue)
                     .Select(x => new BookingViewModel 
                        BookingId = x.BookingId,
                        CustomerReference = x.CustomerReference,
                        Venue = x.Showing.Venue.VenueName,
                        Movie = x.Showing.Movie.MovieName,
                        ShowingDateTime = x.Showing.ShowingDateTime
                     )
                     .ToList()
    return View(bookings);

然后你只需要更新你的视图模型声明和属性以适应:

@model IEnumerable<MovieClubSite.Models.BookingViewModel>

【讨论】:

[img]i.imgur.com/CgIZjUO.png[/img] 我收到一条错误消息,MovieName 和 VenueName 是单独表的一部分,因此视图当前无法获取它们。 那么您也需要将它们包含在您的查询中。我已经更新了答案 .ThenInclude 不包括在 EF6 中,但它在 EF Core 中。我找到了一种解决我在单独答案中发布的问题的方法。感谢一路上的帮助,你一直是一个很好的帮助。我认为您为我指明了正确的方向。【参考方案2】:

我已经通过上面的海报和一些在线搜索解决了这个问题。解决这个问题大约需要 4 个小时,这就是编程:/ 希望这篇文章能帮助其他人解决同样的问题。

查看

        public ActionResult Index()
        
            var bookings = db.Bookings
                             .Include(b => b.Member)
                             .Include(b => b.Showing)
                             .Include(x => x.Showing.Movie)
                             .Include(x => x.Showing.Venue)
                            .ToList();
        return View(bookings);
        

控制器

model IEnumerable<MovieClubSite.Controllers.Booking>

@
    ViewBag.Title = "Booking Manager";


<br />
<h2>Booking Manager</h2>





<ul class="list-group">
    <li class="list-group-item list-group-item-dark">Pick a showing</li>

    @foreach (var item in Model)
    
        <li class="list-group-item list-group-item-action list-group-item-info">
            <div class="float-left">
                <b>Username: </b> @Html.DisplayFor(modelItem => item.CustomerReference)<br />
                <b>Movie: </b>@Html.DisplayFor(modelItem => item.Showing.Movie.MovieName)<br />
                <b>Venue: </b>@Html.DisplayFor(modelItem => item.Showing.Venue.VenueName)<br />
                <b>Date/Time: </b>@Html.DisplayFor(modelItem => item.Showing.ShowingDateTime)<br />
            </div>
            <div class="float-right">
                <a href='@Url.Action("Edit", "Bookings", new  id = item.BookingID )'><img src="~/Resources/pencil.png" style="width: 1.5rem"></a><br />
                <a href='@Url.Action("Delete", "Bookings", new  id = item.BookingID )'><img src="~/Resources/recycle-bin.png" style="width: 1.5rem"></a>
            </div>
        </li>

    
    <a href='@Url.Action("Create", "Bookings")' class="list-group-item list-group-item-action list-group-item-success">

        Add a new showing

    </a>
</ul>
model IEnumerable<MovieClubSite.Controllers.Booking>

@
    ViewBag.Title = "Booking Manager";


<br />
<h2>Booking Manager</h2>





<ul class="list-group">
    <li class="list-group-item list-group-item-dark">Pick a showing</li>

    @foreach (var item in Model)
    
        <li class="list-group-item list-group-item-action list-group-item-info">
            <div class="float-left">
                <b>Username: </b> @Html.DisplayFor(modelItem => item.CustomerReference)<br />
                <b>Movie: </b>@Html.DisplayFor(modelItem => item.Showing.Movie.MovieName)<br />
                <b>Venue: </b>@Html.DisplayFor(modelItem => item.Showing.Venue.VenueName)<br />
                <b>Date/Time: </b>@Html.DisplayFor(modelItem => item.Showing.ShowingDateTime)<br />
            </div>
            <div class="float-right">
                <a href='@Url.Action("Edit", "Bookings", new  id = item.BookingID )'><img src="~/Resources/pencil.png" style="width: 1.5rem"></a><br />
                <a href='@Url.Action("Delete", "Bookings", new  id = item.BookingID )'><img src="~/Resources/recycle-bin.png" style="width: 1.5rem"></a>
            </div>
        </li>

    
    <a href='@Url.Action("Create", "Bookings")' class="list-group-item list-group-item-action list-group-item-success">

        Add a new showing

    </a>
</ul>

【讨论】:

以上是关于如何在 ASP.NET MVC 视图中将主键转换为实际名称/描述符字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET MVC 中将 base64String 转换为 blob 并通过 ajax 发送到控制器?

如何在 ASP.Net MVC 中将登录视图实现为 jQueryUI 对话框

如何在 MVC .ASP NET 中将变量从字符串转换为 int [重复]

如何在asp.net mvc中将数据从视图传递到控制器

如何在 ASP.Net MVC 中将列表对象显示到视图中?

在 asp.net mvc razor 应用程序中将 Datetime C# 类型转换为 Date javascript