简体   繁体   English

EF Core 中的查询非常慢,使用 .Include() 获取多个子实体?

[英]Very slow query in EF Core that fetches multiple children entities with .Include()?

I have this query below that fetches all these children entities (ex. PracticedStyles, ReceivedReviews, InstructedPoses, etc)我在下面有这个查询,它获取所有这些子实体(例如,PracticedStyles、ReceivedReviews、InstructedPoses 等)

All I need is the .count() for these children collections.我只需要这些子集合的 .count() 。

Question - Is there a faster way to run this query to get the counts for these includes, then using this query below?问题- 是否有更快的方法来运行此查询以获取这些包含的计数,然后在下面使用此查询? The run time is ~4-7 seconds and this is with very little data in the DB.运行时间约为 4-7 秒,而且数据库中的数据很少。

var userWithChildren = await _dbContext.Users
        .Include(p => p.Yogabands.Where(p => p.IsActive == true))
        .Include(p => p.PracticedStyles)
        .Include(p => p.PracticedPoses)
        .Include(p => p.ReceivedReviews)
        .Include(p => p.InstructedStyles)
        .Include(p => p.InstructedPoses)
        .Include(p => p.InstructorPrograms)
        .FirstOrDefaultAsync(user => user.UserName == userName);

Absolutely there is.绝对有。 Include is a blunt instrument which returns every row on the join. Include是一个简单的工具,它返回连接上的每一行。 Worse still, because of the way SQL operates you get the results back in a normalized form, meaning that the total number of rows returned is all of those counts you're after multiplied together.更糟糕的是,由于 SQL 的操作方式,您可以以规范化的形式返回结果,这意味着返回的总行数是所有这些计数相乘后的结果。 With as many Includes as you have this could be tens of thousands of rows.使用尽可能多的包含,这可能是数万行。

What you want is a projection, something like this:你想要的是一个投影,像这样:

var userWithChildren = await _dbContext.Users
    .Select(p => new
    {
        user = p,
        YogaBandCount = p.Yogabands.Where(yb => yb.IsActive == true).Count(),
        PracticedStylesCount = p.PracticedStyles.Count(),
        PracticedPosesCount = p.PracticedPoses.Count()
        ReceivedReviewsCount = p.ReceivedReviews.Count(),
        InstructedStylesCount = p.InstructedStyles.Count(),
        InstructedPosesCount = p.InstructedPoses.Count()
        InstructorProgramsCount = p.InstructorPrograms.Count()
    })
    .FirstOrDefaultAsync(p => p.user.UserName == userName);

This will create an anonymous class which has the user on it as well as all the counts you need.这将创建一个匿名类,其中包含用户以及您需要的所有计数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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