我正在使用EF和Fluent API。
所以我有两个有一对多关系的课程
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();
然后我探索房间Collection,我看到每个房间都有她的图像列表,即使我在第一次查询中没有包含也没有投影图像。
这是怎么发生的?
修改 我知道执行了两个查询,这正是我想要的,因为现实世界的第一个查询更复杂并且加载了很多导航属性,我不希望图像参与连接。
我只是想了解上面的代码是如何工作的,我预计我必须手动加入这两个列表,但不知怎的,这是自动完成的。
答案 0 :(得分:2)
父实体下的所有子项,是您使用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());
答案 1 :(得分:0)
我会尝试用一些测试来解释这个场景......
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();
}
同时使用延迟加载和以下模型调整
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();
}