簡體   English   中英

使用 Select 代替 Include

[英]Use Select instead of Include

所以我有一個我想查詢的大表,它太慢了,我得到一個提示,使用 select 比包含更有效。 那么如何在這個大查詢中將包含轉換為 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));

這是 getById 方法,它只占用一行,我有一個 getAll ,它返回一個產品列表,就像這樣。

性能最高的代碼始終是工作量最少的代碼。

“使用 select 更有效”的“提示”的含義可能與回答以下問題有關:“您真的、真的、真的需要返回所有數據嗎?”。

考慮一下,對於您擁有的每個.Include ,EF 將對數據庫進行自己的查詢,以返回由外鍵鏈接的任何記錄。 如果在 memory 中已經有連接的記錄,則在 DB 端或 memory 中執行此操作實際上非常有效。 (取決於您的緩存配置)但是,它將返回引用的整個實體。 這可能沒問題。 但是,如果這 11 個子實體中的每一個以及您在那里連接的 7 個子子實體都相當大怎么辦。 你真的,真的,真的需要返回所有的數據嗎? 或者您可以使用以下方法返回較小的對象:

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
    })

注意:您仍然需要所有這些包含。 但是,EF 會將此請求轉換為對數據庫的更優化的查詢,該查詢僅選擇您實際需要的少數字段,甚至不會從數據庫中返回任何不需要的字段。 這還允許您充分利用數據庫中基礎表上的任何索引。

只是一個想法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM