[英]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);
這個方案的問題是, skip
和take
的記憶發生(從數據庫加載很多帖子進入,因為發出的內存后Include
)。 我只想在獲取用戶的第一個查詢中從數據庫中查詢少量的帖子(而不是包括整個帖子)。 換句話說,我想以某種方式查詢少量的包含數據,而不是全部包含它們。
我該如何實現?
PS:在我的真實代碼中,帖子不是直接位於用戶下,而是位於多個子屬性中。 我只是為了使代碼簡單而省略了它,因為我如何只包含一部分的想法應該仍然相同。
我的真實代碼是為了對情況有更好的了解:
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.