子对象属性的自定义显示名称

时间:2015-07-01 15:41:57

标签: c# asp.net-mvc entity-framework

我正在关注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列出这些内容时,它会在每个标题中显示为“名称”。我可以将数据注释添加到StoreManagerControllerGenreArtist,但我只希望它在此特定实例中显示为“艺术家名称”。当我在“编辑艺术家页面”时,我不希望它如此具体。

我理解我应该通过使用ViewModel来实现这一点,但我仍然感到困惑,因为视图模型仍然只是拉入对象,并且该对象的显示注释在模型本身中设置。

或者更好的是,这是最好留给标记的东西吗?

2 个答案:

答案 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; }
    }
}

虽然我不确定我是从实体继承,而是根据实体创建模型。