繁体   English   中英

在ViewModel中将值从一个模型传递到另一个模型

[英]Passing value from one model to another in a ViewModel

我正在构建我的第一个MVC网站,我正在努力在ViewModel中将值从一个模型传递到另一个模型。 这两个课程是Music and MusicGenre。 在Music中,有一个名为'GenreId'的字段,它是一个int,与MusicGenres中的'Id'字段相关。 我想返回与传递的Id相关的类型名称。

这是我到目前为止所得到的:

        MusicViewModel vmMusic = new MusicViewModel
        {
            Music = _context.Music.SingleOrDefault(c => c.Id == id),
            MusicGenres = _context.MusicGenres.Where(gi => gi.Id == xxx).ToList()
        };
        return View(vmMusic); 

这一切都很好地减去显示正确的流派。 (我用Id替换了xxx,但只使用了Music中的id字段,而不是GenreId字段)

所以xxx是我想传递'GenreId'但我不知道怎么做的地方。 有帮助吗? 谢谢

为了扩展我对这个问题的初步评论,我只是做了类似的事情:

    var music = _context.Music.SingleOrDefault(c => c.Id == id);
    var musicGenres = _context.MusicGenres.Where(gi => gi.Id == music.GenreId).ToList(); // whatever the genre id property is called.
    MusicViewModel vmMusic = new MusicViewModel
    {
        Music = music,
        MusicGenres = musicGenre
    };
    return View(vmMusic); 

您应该将视图模型与持久性模型分开。 视图模型旨在显示您要向用户显示的内容。 持久性模型可能反映您的数据存储结构。

同样从您的示例看起来您可能已经使用了像EntityFramework这样的ORM。 EntityFramework提供导航属性和延迟加载等功能。

无论哪种方式,我强烈不同意接受的答案的方法,当你只需要获得流派名称时,它将音乐及其类型持久性模型发送到视图中。

相反,我会这样做:

持久性模型

您可能在持久性存储中的类型和相册之间存在一对一的关系:

public class Album
{
    public int AlbumId { get; set; }
    public string Title { get; set; }
    public double Price { get; set; }

    public int GenreId { get; set; }
    public Genre Genre { get; set; }
}

public class Genre
{
    public int GenreId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public List<Album> Albums { get; set; }
}

但显然您不希望/需要将持久存储中的所有内容透露给用户。 因此,您创建视图模型并包含要显示的内容。

查看模型

假设您有一个显示所选专辑信息的视图。 您可以创建这样的视图模型:

public class AlbumViewModel
{
    public int AlbumId { get; set; }
    public string AlbumName { get; set; }
    public string Genre { get; set; }
}

然后在相册控制器中,您可以使用任何ORM,延迟加载等构建视图模型:

调节器

如果您碰巧使用EntityFramework并且启用了延迟加载,则可以通过其导航属性获取流派名称:

public ActionResult Details(int id)
{
    var album = _dbContext.Albums.SingleOrDefault(x => x.AlbumId == id);
    if (album == null)
    {
        return HttpNotFound();
    }

    var vm = new AlbumViewModel
    {
        AlbumId = album.AlbumId,
        AlbumName = album.Title,

        // You can get the genre name via Navigation property, and/or lazy
        // loading
        Genre = album.Genre.Name
    };

    return View(vm);
}

现在,在更高级的体系结构中,读取和写入是分开的,称为CQRS。 对于所有读取(即向用户显示信息),您可以直接从执行纯SQL语句构建包含数据的视图模型。

CQS与Dapper

using Dapper;
using System.Data;

...

public class AlbumController : Controller
{
    private readonly IDbConnection _dbConnection;

    public AlbumController(IDbConnection dbConnection)
    {
        _dbConnection = dbConnection;
    }

    public ActionResult Details(int id)
    {
        const string sql = @"
SELECT a.AlbumId, a.Title AS [AlbumName], g.Name AS [Genre]
FROM [Album] a
    JOIN [Genre] g ON a.GenreId = g.GenreId
WHERE a.AlbumId = @albumId;
";

        var vm = _dbConnection.QuerySingleOrDefault<AlbumViewModel>(sql, new {
            albumId = id
        });
        if (vm == null)
        {
           return HttpNotFound();
        }

        return View(vm);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM