MVC MusicStore Artist.Name对象引用未设置为对象的实例

本文关键字:对象 实例 设置 MusicStore Artist Name 对象引用 MVC | 更新日期: 2023-09-27 17:59:30

通过MVC MusicStore学习MVC时,我的头都碎了。"Model.Artist.Name for Details View"页面出现此错误。

My Storecontroller Details方法应该可以。

    public ActionResult Details(int id)
    {
        //returns and albums searched from the id 
        var albums = storeDB.Albums.Find(id);
        return View(albums);
    }

这就是我输出视图的方式

    <li>Price : <%=Model.Price %></li>
    <li>Artist : <%=Model.Artist.Name%></li>

对于这个价格来说,效果很好,它只显示Model.Genre.Name和Artist.Name的错误。我怀疑sampledata.cs中这些属性的声明导致了这个问题

    Artist = artists.Single(a => a.Name == "Aaron Copland & London Symphony Orchestra")

但我对这方面的知识太薄弱,无法弥补。请帮忙。

好吧,这个值是从一个类文件中提取的,看起来像这个

    protected override void Seed(MusicStoreEntities context)
    {
        var artists = new List<Artist>
        {
            new Artist { Name = "Aaron Copland & London Symphony Orchestra" },
            etcetc
        }
         new List<Album>
        {
            new Album { Title = "ABC", Artist= artists.Single(g => g.Name == "Test")}
        }
    }

注意值是如何分配的,我可以访问Model.Title fine(其中Model是简写),但Model.Artist.Name导致了这个错误。

已解决

好吧,通过在Album类的Artist和Genre声明中添加虚拟关键字,就可以开始工作了。但我仍然不确定会发生什么,我希望有人能关心一下。

在我的相册类中,在解决之前,它看起来像这个

public class Album
{
    public int AlbumId { get; set; }
    public int GenreId { get; set; }
    public int ArtistId { get; set; }
    public string Title { get; set; }
    public decimal Price { get; set; }
    public string AlbumArtUrl { get; set; }
    public Genre Genre { get; set; }
    public Artist Artist { get; set; }
}

通过添加虚拟关键字解决了由流派和艺术家引起的错误

    public virtual Artist Artist { get; set; }

不知怎的,我仍然无法证明发生了什么,我希望了解更多。有人想解释一下吗?

它是这样的,相册.cs

namespace MvcMusicStore.Models
{
    public class Album
    {
        public int AlbumId { get; set; }
        public int GenreId { get; set; }
        public int ArtistId { get; set; }
        public string Title { get; set; }
        public virtual Genre Genre { get; set; }
        public virtual Artist Artist { get; set; }
    }
}

使用EF MusicStore.cs

namespace MvcMusicStore.Models
{
    //represent entity framework , handle create ,read , update and del ops 
    public class MusicStoreEntities : DbContext
    {
        public DbSet<Album> Albums { get; set; }
        public DbSet<Genre> Genres { get; set; }
        public DbSet<Artist> Artists { get; set; }
    }
}

并在StoreController.cs 中实现

    MusicStoreEntities storeDB = new MusicStoreEntities();
    public ActionResult Details(int id)
    {
        //returns and albums searched from the id 
        var albums = storeDB.Albums.Find(id);
        return View(albums);
    }

最后是样本数据

protected override void Seed(MusicStoreEntities context)
{
    var artists = new List<Artist>
    {
        new Artist { Name = "Aaron Copland & London Symphony Orchestra" },
        etcetc
    }
     new List<Album>
    {
        new Album { Title = "ABC", Artist= artists.Single(g => g.Name == "Test")}
    }
}

MVC MusicStore Artist.Name对象引用未设置为对象的实例

你说得对。该错误指的是Genre对象和Artist对象尚未实例化,因此试图访问其中任何一个的Name属性都会引发错误。

问题发生在Find()方法中。如果您使用的是LinqToSql、EF、NHibernate或simliar,请检查映射是否正确。

更新:

根据修改后的代码,如果你正在进行artists.Single(g => g.Name == "Test"),那么如果没有名为"Test"或其他名称的艺术家,这将抛出NullReferenceException

我建议用绳子以外的东西来比赛。如果可能,请使用Id进行匹配。这将提供更加可靠的匹配条件。

理想情况下,您应该使用SingleOrDefault()并检查是否返回了null

看起来ArtistName就是null

也就是说,Model的属性Artist不具有对Artist的初始化实例的引用,或者对Artist实例的Name的类似场景的引用。在尝试访问对象之前,您应该始终检查null值:

if (Model.Artist != null)
{
    //do something with artist
}

同样的解释也适用于其他属性,例如Genre

然而,奇怪的是,如果没有Artist满足查询(或不止一个满足查询),那么使用Single只获取单个实体应该抛出异常吗?这是你的确切代码,还是你想要的Artist确实存在的测试?

好吧,通过在Album类中的Artist和Genre声明中添加虚拟关键字来实现它。但我仍然不确定会发生什么,我希望有人能关心一下。

请参见上文。

GenreId、ArtistId和AlbumId不能为空示例:

public int? GenreId { get; set; }