Saya memiliki entitas Post
yang memiliki hubungan satu-ke-banyak dengan Author
dan Comment
. Saya ingin memuat semua Post
s dan menggabungkannya dengan Author
pertama dan semua Comment
s. Kode dengan Include
akan terlihat seperti ini:
Post[] posts = ctx.Posts.Include(p => p.Authors.Take(1)).Include(p => p.Comments).ToArray();
Ada masalah ledakan kartesius pada kueri ini. Jika Post
memiliki n
Comments
, Author
dan Comment
akan diulang n
kali dalam kumpulan hasil.
Solusi #1
Di EF Core 5.0, saya bisa menggunakan Pisahkan Kueri tetapi itu akan menghasilkan 3 kueri ketika saya ingin memuat Post
dengan Author
terlebih dahulu kemudian semua Comment
s.
Solusi #2
Pertama, muat Post
dengan Author
lalu ulangi postingan ke muat secara eksplisit komentar mereka tetapi itu akan menghasilkan n + 1
pertanyaan.
Post[] posts = ctx.Posts.Include(p => p.Authors.Take(1)).ToArray();
foreach (Post post in posts)
ctx.Entry(post).Collection(p => p.Comments).Load();
Solusi #3
Pertama, muat Post
dengan Author
lalu kumpulkan semua id postingan untuk menghasilkan satu kueri guna memuat komentar.
Dictionary<int, Post> postsById = ctx.Posts.Include(p => p.Authors.Take(1)).ToDictionnary(p => p.Id);
Comment[] comments = ctx.Comments.Where(c => postsById.ContainsKey(c.PostId)).ToArray();
foreach (Comment comment in comments)
postsById[comment.PostId].Comments.Add(comment); // How to avoid re-adding comment?
Solusi ini hanya akan menghasilkan 2 kueri tanpa data duplikat, tetapi bagaimana saya bisa menghindari komentar ditambahkan lagi ke postingan? Apakah ada cara yang lebih baik daripada 3 solusi yang diusulkan?
Include
pada akhirnya akan menyebabkan kumpulan hasil yang sangat besar dari kueri SQL seiring dengan bertambahnya jumlah catatan terkait. Saya akhirnya beralih ke ADO untuk jenis kueri ini - ini memungkinkan saya membagi kueri secara manual dan juga menjalankan semuanya secara bersamaan (karena EF tidak aman untuk thread). Peningkatan kinerja terjadi siang dan malam. - person crgolden   schedule 11.12.2020