在学习MusicStore教程中,执行程序->查看唱片详细信息时,弹出以下异常:
代码如下:
Model层Album类结构为:
public class Album
{
public int AlbumId { get; set; }
public int ArtistId { get; set; }
public int GenreId { 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; }
}
Controller层显示该界面的方法为:
public ActionResult Details(int id)
{
var album = storeDB.Albums.Find(id);
return View(album);
}
因为异常显示Genre未实例化,所以开始的解决办法是在Details方法里,将
var album = storeDB.Albums.Find(id);
改为
var album = storeDB.Albums.Include("Genre").Include("Artist").Single(item => item.AlbumId == id);
后,界面显示正常。但是有个疑问——MusicStore教程中并没有这样写呀...
仔细对照代码后,教程中发现Album类关于Genre和Artist的定义中各多了Virtual修饰符,更改后原来的代码执行成功!
关于Virtual,教程中的原文如下:
While we’re there, we’ve also changed the Genre and Artist to virtual properties. This allows Entity Framework to lazy-load them as necessary.
理解为:使用了virtual的类或类集合的好处在于延时加载,只有在使用该数据时,EF再去自动执行数据加载操作。
最后Model层代码如下:
public class Album
{
public int AlbumId { get; set; }
public int ArtistId { get; set; }
public int GenreId { get; set; }
public string Title { get; set; }
//[Required(ErrorMessage="Price is required!")]
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}
Controller中的代码维持原来的不变.