ASP.NET MVC:在一个视图中显示多个模型(一对多关系)

时间:2012-06-04 22:42:19

标签: asp.net-mvc asp.net-mvc-scaffolding

我正在尝试将使用MVCScaffolding和ASP.NET的简单ASP.NET Web应用程序放在一起(我认为是)。 SQL中有一个基本的数据表层:dbo.Albums,dbo.Tracks。

模型很简单。对于专辑:

public class Albums {
public int ID { get; set; }
public string Artist { get; set; }
    public string AlbumTitle { get; set; }
public string Notes { get; set; } 
}

public class Tracks {
public int ID { get; set; }
public int AlbumID { get; set; }
public string TrackTitle { get; set; }
public string Notes { get; set; }
}

基本的CRUD视图已构建且工作正常。但是,我正在尝试构建一个视图,显示Album模型数据,后跟一个表,给定AlbumId的每个跟踪记录有一行。从本质上讲,这是Details视图,后跟来自MVCScaffolding模板的Index视图,但它使用两个模型并且有一个参数(来自ID表的Albums)。

我尝试将模型添加到一起以从那里访问数据,但我无法弄清楚如何迭代列表(索引视图使用@model IEnumerable<Music.Models.Tracks>)。这是组合模型:

public class AlbumsExtended
{
    public Albums Albums { get; set; }
    public Tracks Tracks { get; set; }
}

我正在尝试使用@model Music.Models.AlbumsExtended在AlbumsExt.cshtml中访问它。控制器如下所示:

public ViewResult AlbumExt(int id)
    {
        return View(tracksRepository.All.Where(tracks => tracks.AlbumId == id));
    }

但显然这是不正确的。

1 个答案:

答案 0 :(得分:4)

鉴于你的专辑和曲目的结构,最好在专辑和曲目之间有一个直接的1对多关系,这样一张专辑可以有很多曲目。无论曲目可能出现多少张专辑,您的模型都可能如下:

public class Albums {
    public int ID { get; set; }
    public string Artist { get; set; }
    public string AlbumTitle { get; set; }
    public string Notes { get; set; } 
    public IQueryable<Track> Tracks { get; set; }
}

public class Track {
    public int ID { get; set; }
    public int AlbumID { get; set; }    // This may be unnecessary 
    public string TrackTitle { get; set; }
    public string Notes { get; set; }
}

这将允许您的数据层填充属于特定相册的所有曲目,但如果您不需要知道曲目,则它可以保持为空。但是您的数据层只需要获取相册,然后使用IQueryable对象填充Tracks属性。

public ViewResult AlbumExt(int id)
{
    Album album = albumRepository.All.Where(a => a.ID == id);
    album.Tracks = tracksRepository.All.Where(t => t.AlbumId == id);
    return View(album);
}

这将为您提供单个模型,但仍可通过视图中的Model.Tracks属性访问所有相关轨道:

@model MyNameSpace.Album

@{
    foreach (var track in Model.Tracks)
    {
        <text>
            <h1>@track.TrackTitle</h1><br />
        </text>
    }    
}