I am trying to GroupJoin some data with an IQueryable and project that data into an anonymous type. The original entity that I am GroupJoining onto has an ICollection navigation property (ie. one:many). I want to eager load that property so I can access it after the group join without EF going back to the DB. I know that Include() doesn't work when you use a GroupJoin, but the following code is the only way I have found to make it eager load the collection (ContactRoomRoles):
using (var context = new MyDbContext()) {
var foundRooms = context.Rooms.Include(rm => rm.ContactRoomRoles);
foundRooms.ToList(); // <-- Required to make EF actually load ContactRoomRoles data!
var roomsData = foundRooms
.GroupJoin(
context.Contacts,
rm => rm.CreatedBy,
cont => cont.Id,
(rm, createdBy) => new {
ContactRoomRoles = rm.ContactRoomRoles,
Room = rm,
CreatedBy = createdBy.FirstOrDefault()
}
)
.ToList();
var numberOfRoles1 = roomsData.ElementAt(1).Room.ContactRoomRoles.Count();
var numberOfRoles2 = roomsData.ElementAt(2).Room.ContactRoomRoles.Count();
var numberOfRoles3 = roomsData.ElementAt(3).Room.ContactRoomRoles.Count();
}
If I remove the foundRooms.ToList(), EF goes off to the database 3 times to populate my numberOfRoles variables at the end, but with foundRooms.ToList() it doesn't - it just eager loads the data in one query upfront.
Although this works, it feels like a total hack. I'm just calling .ToList() for the side-effect of making EF actually load the collection data. If I comment that line out, it goes to the database any time I try to access ContactRoomRoles. Is there a less hacky way to make EF eager load that navigation property?
NOTE: I want to use the navigation property rather than projecting it into a new property of the anonymous type because AutoMapper wants to access Room.ContactRoomRoles when it's mapping onto a DTO object.