3.2.6 启用延迟装入特性
假设Guestbook与Member之间的关联是属于“多对一”的关系,如3.2.5节“设计模型之间的关联性”的第一个演示所示。
public class Guestbook { public int Id { get; set; } [Required] public string Message { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime CreatedOn { get; set; } public Member Member { get; set; } } public class Member { public int Id { get; set; } [Required] [MaxLength(5)] public string Name { get; set; } [MaxLength(200)] public string Email { get; set; } public ICollection<Guestbook> Guestbooks { get; set; } }
假设有个guestbook对象(Guestbook类型)要取得Message字段的值,只要输入以下程序即可:
guestbook.Message
如果要取得Guestbook关联的Member数据表中的Name字段,则通过“点表示法”加上一个“点”与“属性名称”就可以取得数据,演示如下:
guestbook.Member.Name
但是如果在控制器中没有通过Include方法显示加载关联类Member,代码如下,运行程序则会报错,显示“未将对象设置到引用类上”的错误消息。
public ActionResult Index(string category) { var guestbookModel = storeDB.Guestbooks.ToList(); return View(guestbooksModel); }
解决方法是,要么在控制器方法中加上Include显示加载关联数据(如下代码),要么使用Virtual延迟装入数据。
var guestbookModel = storeDB.Guestbooks.Include("Member").ToList();
若要在Code First模型类别中启用“延迟装入”特性,必须在属性声明时加上virtual关键词,才会启用“延迟装入”特性。我们应该将Guestbook修改为以下程序代码,才能让上述语法自动取得数据:
public class Guestbook { public int Id { get; set; } [Required] public string Message { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime CreatedOn { get; set; } public virtual Member Member { get; set; } } public class Member { public int Id { get; set; } [Required] [MaxLength(5)] public string Name { get; set; } [MaxLength(200)] public string Email { get; set; } public virtual ICollection<Guestbook> Guestbooks { get; set; } }
使用ORM框架,基本上都会添加“延迟装入”的特性支持,Entity Framework当然也不例外。当使用Entit Framework的ObjectContext与DbContext操作数据时,默认都启用“延迟装入”。也就是当我们在应用程序里通过LINQ to Entity查询数据时,如果遇到关联数据尚未装入的情况,Entity Framework会自动帮我们再向数据库索取关联数据,全自动地取得关联数据,大幅降低编写访问关联数据的程序代码。