Вы должны отделить ваши модели представления от ваших моделей персистентности. Представление модели предназначено для отображения того, что вы хотите отобразить пользователям. Модель постоянства может отражать ваши структуры хранения данных.
Также из вашего примера похоже, что вы, возможно, уже использовали 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);
}
}