简体   繁体   中英

EF Core 3.0 .Include() chain taking ~5-10x longer than 2.2

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM