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

时间:2011-06-20 10:52:09

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

在通过MVC MusicStore学习MVC的过程中开始捣乱。详细信息视图页面的Model.Artist.Name出现此错误。

我的Storecontroller详细信息方法应该没问题。

    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的错误。我怀疑samplesata.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(其中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; }

不知何故,我仍无法证明所发生的事情并希望了解更多信息。有人在乎解释吗?

就像这样,Album.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")}
    }
}

4 个答案:

答案 0 :(得分:3)

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

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

<强>更新

根据修改后的代码,如果您正在执行artists.Single(g => g.Name == "Test"),那么如果没有名称为“Test”的艺术家或其他任何人,则会抛出NullReferenceException

我建议在除了字符串之外的其他内容上进行匹配。如果可能,使用Id执行匹配。这将提供更可靠的匹配条件。

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

答案 1 :(得分:2)

看来ArtistNamenull

也就是说Artist的属性Model没有对Artist的初始化实例的引用,或Name的{​​{1}}的同样方案{1}}实例。在尝试访问对象之前,应始终检查Artist值:

null

同样的解释也适用于其他属性,例如if (Model.Artist != null) { //do something with artist }

奇怪的是,如果没有Genre满足查询(或多于一个这样的满足),使用Single来获取单个实体应该抛出异常 - 这是您确切的代码,或者您想要的Artist确实存在的测试?

答案 2 :(得分:2)

好吧,通过在Album类的Artist和Genre声明中添加虚拟关键字来实现它。但是我仍然不确定会发生什么事情,并且希望有人能够照亮一些灯光。

见上文。

答案 3 :(得分:0)

GenreId,ArtistId和AlbumId不能为空 例如:

public int? GenreId { get; set; }