Передача значения из одной модели в другую в ViewModel - PullRequest
0 голосов
/ 09 мая 2019

Я создаю свой первый веб-сайт MVC и пытаюсь передать значение из одной модели в другую в ViewModel.Два класса - это музыка и MusicGenre.В Music есть поле GenreId, которое является int и связано с полем Id в MusicGenres.Я хочу вернуть название жанра, относящееся к пропущенному идентификатору.

Вот что я получил до сих пор:

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

Все это прекрасно воспроизводится без отображения правильного жанра.(Я заменил xxx на Id, но он просто использует поле id из Music, а не поле GenreId)

Так что в xxx я хочу передать GenreId, но не знаю как.Любая помощь?Спасибо

Ответы [ 2 ]

0 голосов
/ 09 мая 2019

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

Также из вашего примера похоже, что вы, возможно, уже использовали ORM, как EntityFramework. 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.

CQRS с 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);
    }
}

0 голосов
/ 09 мая 2019

Чтобы расширить мой первоначальный комментарий к вопросу, я бы просто сделал что-то вроде:

    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); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...