Cześć.
Projekt w .Net5 (Core).
Poniżej cały kontroler z zapytaniem.
W skrócie, mamy wyrazy (Word), wyrazy mają definicje (Clue), definicja ma wiele tagów (Tag) i kategorii (Category).
Kiedy próbuję zwrócić words
z kontrolera to zapytanie praktycznie się nie kończy. Na prostych niewielkich danych zauważyłem, że JSON ma cykle, czyli te same dane znajdują się w nim wielokrotnie.
Wpadłem na pomysł żeby ręcznie wynulować referencje, po których nie chciałem żeby serializator schodził podczas serializacji (głównie wsteczne referencje). Dopóki nie wynulowałem dosłownie wszystkich takich, to potrafiłem dostać JSON 40MB. Dopiero kiedy wynulowałem wszystkie dostaję ładne odpowiedzi po kilkanaście/kilkadziesiąt kilobajtów, a kod wykonuje się szybciutko. Tak wygląda to "nulowanie" i cały kontroler z zapytaniem:
[HttpGet]
[Route("{lang_id}/Words/{likePattern}")]
public List<Word> GetWordsByFragAndLang(int lang_id, string likePattern)
{
var query = _context.Word
.Include(w=> w.Clue)
.ThenInclude(clue=>clue.IdLevelNavigation)
.Include(w=> w.Clue)
.ThenInclude(clue=>clue.TagClue)
.ThenInclude(cc=>cc.IdTagNavigation)
.Include(w=> w.Clue)
.ThenInclude(clue=>clue.CategoryClue)
.ThenInclude(cc=>cc.IdCategoryNavigation)
.Where(w=> EF.Functions.Like(w.Word1, likePattern) && w.IdDictionaryNavigation.LangId==lang_id);
var words = query.ToList();
words.ForEach(word=>
{
foreach(var clue in word.Clue)
{
clue.IdWordNavigation = null;
clue.IdLangNavigation = null;
// level
clue.IdLevelNavigation.Clue = null;
// tag
foreach(var tagClue in clue.TagClue)
{
tagClue.IdClueNavigation = null;
tagClue.IdTagNavigation.TagClue = null;
tagClue.IdTagNavigation.Clues = null;
tagClue.IdTagNavigation.Lang = null;
tagClue.IdTagNavigation.WordPackTag = null;
}
// category
foreach(var categoryClue in clue.CategoryClue)
{
categoryClue.IdClueNavigation = null;
categoryClue.IdCategoryNavigation.CategoryClue = null;
categoryClue.IdCategoryNavigation.Clues = null;
categoryClue.IdCategoryNavigation.Lang = null;
categoryClue.IdCategoryNavigation.WordPackCategory = null;
}
}
});
return words;
}
Używam NewtonsoftJson. W Startup.cs mam:
services.AddControllersWithViews().AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
Domyślam się, że nie tak to powinno wyglądać. Co robię nie tak ლ(ಠ_ಠ ლ) ?