我正在关注ASP.NET MVC 5一书,但我发现这本书似乎没有划伤。我有一个Album模型:
Counter2 = 17
For Counter1 = 12 To 150
Dim S As Worksheet
Dim R As Worksheet
Dim SL As Range
Dim RL As Range
Set R = Sheets("Front")
Set S = Sheets("CHECK LIST")
Set SL = S.Range(Cells(Counter1, 1), Cells(Counter1, 10))
Set RL = R.Range(Cells(Counter2, 1), Cells(Counter2, 10))
Set curCell = Worksheets("CHECK LIST").Cells(Counter1, 6)
Set checkCell = Worksheets("Front").Cells(3, 5)
If curCell.Value = checkCell.Value Then
With S
.SL.Copy
End With
With R
.RL.PasteSpecial
End With
Counter2 = Counter2 + 1
End If
Next Counter1
简而言之,namespace MvcMusicStore.Models
{
public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public virtual string Title { get; set; }
public virtual decimal Price { get; set; }
public virtual string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}
}
和Genre
模型都有一个名为Artist
的字段。当我使用Name
列出这些内容时,它会在每个标题中显示为“名称”。我可以将数据注释添加到StoreManagerController
和Genre
等Artist
,但我只希望它在此特定实例中显示为“艺术家名称”。当我在“编辑艺术家页面”时,我不希望它如此具体。
我理解我应该通过使用ViewModel来实现这一点,但我仍然感到困惑,因为视图模型仍然只是拉入对象,并且该对象的显示注释在模型本身中设置。
或者更好的是,这是最好留给标记的东西吗?
答案 0 :(得分:1)
如果您正确使用视图模型,则不会。许多人最终创建了视图模型,如:
public class FooViewModel
{
public Foo MyFoo { get; set; }
}
那只是浪费时间。相反,您查看模型应该完全代表您编辑的任何实体,这意味着,您不是仅仅引用实体,而是在视图模型中为要查看/编辑的实体中的所有属性创建属性。然后,在您的控制器操作中,您将“映射”到您的实体和视图模型之间,也就是说,您只需将属性设置为具有相应属性值的属性。
在你的情况下,你需要这样的东西:
public class AlbumViewModel
{
public string Title { get; set; }
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
public GenreViewModel Genre { get; set; }
public ArtistViewModel Artist { get; set; }
}
public class ArtistViewModel
{
public string Name { get; set; }
...
}
public class GenreViewModel
{
...
}
然后,您可以将显示名称设置为此视图模型上的任何内容。如果在另一个上下文中需要不同的显示名称,请为其创建单独的视图模型。
此外,所有virtual
的内容如何? virtual
关键字仅表示属性/方法可以被子类覆盖。虽然它在技术上并没有伤害任何东西,只是让一切都变得虚拟,但它的代码味道,除非你真的想要被覆盖的东西,甚至是第一个被子类化的东西。传统上,在实体上,您唯一要添加virtual
的是导航属性,因为这允许实体框架将其延迟加载逻辑应用于您的实体。 (它实际上动态创建实体的子类,称为“代理”,将延迟加载逻辑添加到导航属性的getter。)如果您没有导航属性,或者即使您只是不想启用延迟加载对于那个导航属性,你不应该使用虚拟,除非你真的想要。
答案 1 :(得分:0)
我可能会做这样的事情。
public class AlbumViewModel
{
public int AlbumId { get; set; }
public AlbumGenre Genre { get; set; }
public AlbumArtist Artist { get; set; }
}
[MetadataType(typeof(AlbumArtistMetadata))]
public class AlbumArtist : Artist {
private class AlbumArtistMetadata {
[Display(Name="Artist Name")]
public string Name { get; set; }
}
}
[MetadataType(typeof(AlbumGenreMetadata))]
public class AlbumGenre : Genre
{
private class AlbumGenreMetadata
{
[Display(Name = "Genre Name")]
public string Name { get; set; }
}
}
虽然我不确定我是从实体继承,而是根据实体创建模型。