简体   繁体   English

使用 Select 代替 Include

[英]Use Select instead of Include

so I have this big table that I want to query and it's so slow, I got a tip that using select is more efficient than include.所以我有一个我想查询的大表,它太慢了,我得到一个提示,使用 select 比包含更有效。 so how can I convert include to select, in this big query.那么如何在这个大查询中将包含转换为 select。

    ProductEntity? i = await _context.Set<ProductEntity>()
        .Include(i => i.Media)
        .Include(i => i.Categories)
        .Include(i => i.Locations)
        .Include(i => i.Reports)
        .Include(i => i.Comments)!.ThenInclude(x => x.LikeComments)
        .Include(i => i.Bookmarks)
        .Include(i => i.Votes)
        .Include(i => i.User)!.ThenInclude(x => x.Media)
        .Include(i => i.User)!.ThenInclude(x => x.Categories)
        .Include(i => i.Forms)!.ThenInclude(x => x.FormField)
        .Include(i => i.Teams)!.ThenInclude(x => x.User)!.ThenInclude(x => x.Media)
        .Include(i => i.VoteFields)!.ThenInclude(x => x.Votes)
        .AsNoTracking()
        .FirstOrDefaultAsync(i => i.Id == id && i.DeletedAt == null);
    return new GenericResponse<ProductEntity>(_mapper.Map<ProductEntity>(i));

and this is getById method, which just takes one row, I have a getAll that returns a list of products just like this.这是 getById 方法,它只占用一行,我有一个 getAll ,它返回一个产品列表,就像这样。

The most performant code is always the code that does the least amount of work.性能最高的代码始终是工作量最少的代码。

It's possible that what was meant by the 'tip' that "using select is more efficient" may have more to do with answering the question: "do you really, really, really need all that data to be returned?". “使用 select 更有效”的“提示”的含义可能与回答以下问题有关:“您真的、真的、真的需要返回所有数据吗?”。

Consider, for every .Include you have, EF will be making it's own query to the database to return whatever records are linked by the foreign keys.考虑一下,对于您拥有的每个.Include ,EF 将对数据库进行自己的查询,以返回由外键链接的任何记录。 It's actually pretty efficient on doing that either on the DB side, or in memory if it already has the connected records in memory.如果在 memory 中已经有连接的记录,则在 DB 端或 memory 中执行此操作实际上非常有效。 (depending on your caching configuration) However, it's going to return the entire Entity referenced. (取决于您的缓存配置)但是,它将返回引用的整个实体。 Which may be fine.这可能没问题。 But, what if each of those 11 sub-entities plus the 7 sub-sub-entities that you have connecting there are each rather large.但是,如果这 11 个子实体中的每一个以及您在那里连接的 7 个子子实体都相当大怎么办。 Do you really, really, really need to return all of that data?你真的,真的,真的需要返回所有的数据吗? Or could you return smaller objects using something like:或者您可以使用以下方法返回较小的对象:

var mySmallerObject = await _context.Set<ProductEntity>()
    .Include(i => i.Media)
    .Include(i => i.Categories)
    . . .
    .Select(_ => new SomeMuchSmallerObject {
        SomeFieldOnProduct = _.SomeFieldOnProduct, 
        TheOnlyThingINeedFromMedia = _.Media.TheOnlyThingINeedFromMedia,
        TheOnlyCategoryFieldINeed = _.Categories.TheOnlyCategoryFieldINeed,
        . . . // etc
    })

Note: You would still need all those Includes.注意:您仍然需要所有这些包含。 However, EF will translate this request into a much more optimized query to the DB that only selects the few fields you actually need, and not even return any of the unwanted fields from the database.但是,EF 会将此请求转换为对数据库的更优化的查询,该查询仅选择您实际需要的少数字段,甚至不会从数据库中返回任何不需要的字段。 This also allows you to take full advantage of any indexes you have on the underlying tables in the DB.这还允许您充分利用数据库中基础表上的任何索引。

Just a thought.只是一个想法。

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

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