Reputation: 1026
I'm having trouble with a large EF Core query that has a lot of chained .Include()
.
I have a linq query that looks like this:
_context.Equipment.Include(x => x.Group)
.Include(x => x.Status)
.Include(x => x.Area)
.Include(x => x.EquipmentType)
.Include(x => x.Parts).ThenInclude(x => x.ChildrenParts)
.Include(x => x.Parts).ThenInclude(x => x.ParentParts)
.Include(x => x.Parts).ThenInclude(x => x.Vendor)
.Include(x => x.Notes)
.Include(x => x.Department)
.Include(x => x.PMaintenance)
.Include(x => x.SystemInfo).ThenInclude(x => x.SystemUsers)
.Include(x => x.SystemInfo).ThenInclude(x => x.Frameworks)
.Include(x => x.SystemInfo).ThenInclude(x => x.VideoCards)
.Include(x => x.SystemInfo).ThenInclude(x => x.StorageDrives)
.Include(x => x.SystemInfo).ThenInclude(x => x.Software)
.Include(x => x.SystemInfo).ThenInclude(x => x.NetworkAdapters)
.Include(x => x.SystemInfo).ThenInclude(x => x.Printers)
.Include(x => x.MaintenanceHours)
.Include(x => x.Attachments)
.Include(x => x.Request)
.FirstOrDefault(x => x.EquipmentId == id);
In EF Core 2.2, this took less than a few seconds to evaluate. Now on EF Core 3.0, it takes about 15 seconds to complete. What about EF Core 3 made this so slow? I read here that ef now creates one sql statement per linq query, but I don't see how the statement would have changed in this instance. Can I do something to this query that would decrease the execution time?
EDIT: This is on SQL Server v11.0.3
Upvotes: 4
Views: 1114
Reputation: 367
Try it like this. You might need to change some of the "Select" and "SelectMany" options and the Id field names as you did not post the context.`
var query = _context.Equipment.Include(x => x.Group)
.Include(x => x.Status)
.Include(x => x.Area)
.Include(x => x.EquipmentType)
.Include(x => x.Notes)
.Include(x => x.Department)
.Include(x => x.PMaintenance)
.Include(x => x.MaintenanceHours)
.Include(x => x.Attachments)
.Include(x => x.Request).FirstOrDefault(x => x.EquipmentId == id);
query.Include(x => x.Parts).ThenInclude(x => x.ChildrenParts).SelectMany(x => x.Parts).Where(a => query.Select(q => q.PartsId).Contains(a.Id)).Load();
query.SelectMany(x => x.Parts).SelectMany(x => x.ChildrenParts).Load();
query.SelectMany(x => x.Parts).SelectMany(x => x.ParentParts).Load();
query.SelectMany(x => x.Parts).Select(x => x.Vendor).Load();
query.Include(x => x.SystemInfo).ThenInclude(x => x.SystemUsers).SelectMany(x => x.SystemInfo).Where(a => query.Select(q => q.SystemInfoId).Contains(a.Id)).Load();
query.SelectMany(x => x.SystemInfo).SelectMany(x => x.Frameworks).Load();
query.SelectMany(x => x.SystemInfo).SelectMany(x => x.VideoCards).Load();
query.SelectMany(x => x.SystemInfo).SelectMany(x => x.StorageDrives).Load();
query.SelectMany(x => x.SystemInfo).SelectMany(x => x.Software).Load();
query.SelectMany(x => x.SystemInfo).SelectMany(x => x.NetworkAdapters).Load();
query.SelectMany(x => x.SystemInfo).SelectMany(x => x.Printers).Load();
query.ToList();
Hope this helps.
Upvotes: 1