簡體   English   中英

如何僅從導航屬性中查詢一小部分(不包括該屬性中的所有數據)?

[英]How to query only a small part from a navigation property (without including all data in that property)?

我有一個小場景:

var user = await dbContext.Users
        .Include(u => u.Posts)
    .SingleOrDefaultAsync(u => u.Id == userId);

return user
    .SelectMany(u => u.Posts)
    .Skip(someStartIndex)
    .Take(someCount);

這個方案的問題是, skiptake的記憶發生(從數據庫加載很多帖子進入,因為發出的內存后Include )。 我只想在獲取用戶的第一個查詢中從數據庫中查詢少量的帖子(而不是包括整個帖子)。 換句話說,我想以某種方式查詢少量的包含數據,而不是全部包含它們。

我該如何實現?

PS:在我的真實代碼中,帖子不是直接位於用戶下,而是位於多個子屬性中。 我只是為了使代碼簡單而省略了它,因為我如何只包含一部分的想法應該仍然相同。

UPDATE

我的真實代碼是為了對情況有更好的了解:

public async Task<IEnumerable<Post>> GetPostsFromFollowsAsync(Guid userId, int count, int startIndex)
{
    //TODO rewrite this ugly query!!!
    var user = await dbContext.Users
        .Include(u => u.UserFollowing)
            .ThenInclude(uf => uf.FollowingUser)
                .ThenInclude(u => u.Posts)
                    .ThenInclude(p => p.Writer)
                        .ThenInclude(u => u.Profile)
        .Include(u => u.UserFollowing)
            .ThenInclude(uf => uf.FollowingUser)
                .ThenInclude(u => u.Posts)
                    .ThenInclude(p => p.PostLikes)
        .Include(u => u.UserFollowing)
            .ThenInclude(uf => uf.FollowingUser)
                .ThenInclude(u => u.Posts).
                    ThenInclude(p => p.PostCategories)
                        .ThenInclude(pc => pc.Category)
        .Include(u => u.UserFollowing)
            .ThenInclude(uf => uf.FollowingUser)
                .ThenInclude(u => u.Posts)
                    .ThenInclude(p => p.Comments)
        .SingleOrDefaultAsync(u => u.Id == userId);

    return user
        .UserFollowing
        .Select(uf => uf.FollowingUser)
        .SelectMany(u => u.Posts)
        .Skip(startIndex)
        .Take(count);
}

在這種特定情況下,您可以從“ Posts開始查詢,並使用反向導航屬性進行過濾/其他包括:

var userPosts = await dbContext.Posts
    .Include(p => p.User)
    // other includes ...
    .Where(p => p.User.Id == userId)
    .Skip(someStartIndex)
    .Take(someCount)
    .ToListAsync();

這樣,“ Skip / Take將發生在服務器端。

更新:實際的結構不會改變概念。 由於多對多關系,您只需要向后導航並將用戶ID過濾器更改為Any

return await dbContext.Posts
    .Include(p => p.Writer) // Parent info
        .ThenInclude(u => u.UserFollowers)
            .ThenInclude(uf => uf.FollowerUser)
    .Include(p => p.Writer) // Child info
        .ThenInclude(u => u.Profile)
    .Include(p => p.PostLikes)
    .Include(p => p.PostCategories)
        .ThenInclude(pc => pc.Category)
    .Include(p => p.Comments)
    .Where(p => p.Writer.UserFollowers.Any(uf => uf.FollowerUser.Id == userId))
    .Skip(startIndex)
    .Take(count)
    .ToListAsync();

暫無
暫無

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

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