在通过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")}
}
}
答案 0 :(得分:3)
你是对的。该错误指的是Genre对象和Artist对象尚未实例化,因此尝试访问其中任何一个的Name属性都会引发错误。
问题发生在Find()方法中。如果您使用的是LinqToSql,EF,NHibernate或simliar,请检查您的映射是否正确。
<强>更新强>
根据修改后的代码,如果您正在执行artists.Single(g => g.Name == "Test")
,那么如果没有名称为“Test”的艺术家或其他任何人,则会抛出NullReferenceException
。
我建议在除了字符串之外的其他内容上进行匹配。如果可能,使用Id执行匹配。这将提供更可靠的匹配条件。
理想情况下,您应该使用SingleOrDefault()
并检查是否返回null
。
答案 1 :(得分:2)
看来Artist
或Name
是null
。
也就是说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; }