Reputation: 87
I'm using EF with Fluent API.
So I have two classes with a one to many relationship
public class Room {
//list of properties
public List<Image> Images {get; set; }
}
public class Image {
public Room Room {get; set; }
}
If I first ask for the rooms
var rooms = ctx.Rooms.ToList();
And then I ask for the images
var images = ctx.Images.ToList();
And then I explore the rooms Collection, I see that each room has her list of images, even If i didn't Included nor Projected images in the first query.
How does this happen?
EDIT I know that two queries are performed, and that's exactly what I want, since the real world first query is more complex and a lot of navigation property are loaded, I don't want the images get involved in the joins.
I just want to understand how does the code above can work, I expected that I had to manually join the two lists, but somehow this is done automatically.
Upvotes: 1
Views: 104
Reputation: 125187
All children under the parent entity, are those you loaded using var images = ctx.Images.ToList();
Exactly themselves; Its because of relation between parent and child that you defined using code first conventions or api, so they are listed there.
I suppose that you have disabled lazy loading, and so you should not worry about performance because they don't load twice. The are those images that you load yourself expelicitly.
Here is a simple test to get the concept. I have a context having Parent
entity and Child
entity with a relation defined between them:
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());
Upvotes: 2
Reputation: 820
I'll try and explain the scenario with some tests...
public class Room {
public int Id {get; set;}
public List<Image> Images {get; set; }
}
public class Image {
public Room Room {get; set; }
}
I'd expect all tests to pass...
[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();
}
Also with Lazy Loading on and the following model tweak
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();
}
Upvotes: 0