实体框架导航属性加载
本文关键字:加载 属性 导航 框架 实体 | 更新日期: 2023-09-27 18:19:49
我使用的是带有Fluent API的EF。
所以我有两个类,有一对多关系
public class Room {
//list of properties
public List<Image> Images {get; set; }
}
public class Image {
public Room Room {get; set; }
}
如果我第一次问房间
var rooms = ctx.Rooms.ToList();
然后我要图像
var images = ctx.Images.ToList();
然后我浏览了房间集合,我发现每个房间都有她的图像列表,即使我在第一个查询中没有包含或投影图像。
这是怎么发生的?
编辑我知道要执行两个查询,这正是我想要的,因为现实世界中的第一个查询更复杂,并且加载了很多导航属性,所以我不希望图像参与连接。
我只是想了解上面的代码是如何工作的,我原以为我必须手动连接这两个列表,但不知何故,这是自动完成的。
父实体下的所有子实体都是使用var images = ctx.Images.ToList();
加载的子实体,它们本身就是;这是因为您使用代码优先约定或api定义了父级和子级之间的关系,所以它们被列在那里。
我想您已经禁用了延迟加载,所以您不应该担心性能,因为它们不会加载两次。这些是你自己直接加载的图像。
这里有一个简单的测试来获得这个概念。我有一个具有Parent
实体和Child
实体的上下文,它们之间定义了关系:
var db = new MyDbContext();
db.Configuration.LazyLoadingEnabled = false;
var parents = db.Parents.ToList();
//Shows False, So childs are not loaded.
Console.WriteLine(parents.Any(x => x.Childs.Count() > 0).ToString());
var childs = db.Childs.ToList();
//Shows True, We didn't loads Parents again, and EF only relates them.
Console.WriteLine(parents.Any(x => x.Childs.Count() > 0).ToString());
我将尝试用一些测试来解释这个场景。。。
public class Room {
public int Id {get; set;}
public List<Image> Images {get; set; }
}
public class Image {
public Room Room {get; set; }
}
我希望所有的测试都能通过…
[TestMethod]
public void NoLazyLoadingAndNoEagerLoading()
{
var _db = new dbContext();
var rooms = _db.Rooms.ToList();
//All images will be null
Assert.IsFalse(rooms.Any(x => x.Images != null));
_db.Dispose();
}
[TestMethod]
public void NoLazyLoadingAndNoEagerLoading()
{
var _db = new dbContext();
var rooms = _db.Rooms.Include(x => x.Images).ToList();
//We have eager loaded them in the first query.
Assert.IsTrue(rooms.Any(x => x.Images != null));
_db.Dispose();
}
同样带有Lazy Loading和以下型号调整
public class Room {
public int Id {get; set;}
public virtual List<Image> Images {get; set; }
}
public void NoLazyLoadingAndNoEagerLoading()
{
var _db = new dbContext();
var rooms = _db.Rooms.ToList();
//Now lazy loading should kick in,
//Entity framework will make more calls to the db and return Images
Assert.IsFalse(rooms.Any(x => x.Images != null));
_db.Dispose();
}