急切加载,实体框架

时间:2021-03-17 04:33:24

标签: c# asp.net-mvc entity-framework eager-loading

我有一个专辑类和两个与之相关的类,流派和艺术家。我使用预先加载来加载专辑对象和链接的实体:

var albums = db.Albums.Include(a => a.Artist).Include(a => a.Genre);

加载后,我尝试从数据集中的相册对象访问链接实体的属性,但导航属性为空

Album album = db.Albums.Find(id);
var name = album.Genre.Name;

name 为空。

我的问题是,在预先加载后,专辑数据集中加载的对象是否包含对链接实体“艺术家”和“流派”的引用?

我不想激活延迟加载。

谢谢

1 个答案:

答案 0 :(得分:0)

当延迟加载启用时,导航属性(链接实体或实体集合)会在您第一次访问时自动加载。这就是为什么只要 DbContext 尚未释放或者之前已访问过 album.Genre 属性(某个专辑的),Genre 就可以正常工作。

当延迟加载禁用时,您就没有这种灵活性。您需要急切地(或明确地)加载链接的实体。使用 Include()(急切加载)是正确的开始。但是,由于 albums 尚未具体化(未加载到内存中),因此尝试通过执行 不同 查询来访问 Genre 属性(这就是 db.Albums.Find() do) 会失败。

这里有两个选项...

实现查询:

var albums = db.Albums.Include(a => a.Artist).Include(a => a.Genre).ToList();
Album album = db.Albums.Find(id);
// Works because all `Album.Genre` **of all `Album` records** is loaded into the EF cache.
var name = album.Genre.Name;

使用包含链接实体的相同查询查找目标相册:

var albums = db.Albums.Include(a => a.Artist).Include(a => a.Genre)
// This will force EF to load the "included" entities for this one specific record.
Album album = albums.FirstOrDefault(a => a.Id == id);
var name = album.Genre.Name;
相关问题