❔ EF Core LINQ - Many to Many Search with && and ||
Hi there,
I have a 3 table structure for file storage that I would like to search, consisting of the following:
I would like to search files by assigned labels. I want to provide AND and OR groups for this search, so a search by
LabelEntity.Id
might look like so:
(1 || 2) && (5 || 7 || 12) && 17 && (4 || 6)
I have struggled for a while to work out an efficient way to do this. I will always have the IDs of the labels I want to search by as provided in the example, those are looked up beforehand.
I'd like to formulate this into a fast, efficient linq query(s)19 Replies
First and foremost, provide a navigation property from
File
to FileLabel
, or even just to Label
directly
Then you can go through thatThis is actually just a cut down example
There's actually some navigations for these
That's good
The actual objects at a lot bigger so I just wrote up some super basic examples to give people an idea of the data structure
You'll probably need something like
😂
The problem is having both && and || together which complicates it even more
Only this comes to mind
hmmmm
Or you could make all those wheres into one, ig
Lemme see if I have sufficiently butchered this solution in a way that makes your answer not feasable and our time in this chat even more painful
I have! That's nice
I don't actually have a direct navigation from File to Label and vice versa
builder.HasMany(e => e.Labels).WithMany(f => f.Files);
Is that actually good enough? 🤔
It doesn't have a way to navigate to that through the mapping entity and I don't know if it'll work that out itself
Oh no I am just a professional idiot. It has a .UsingEntity<T>I mean, this will work as well
Your select for the label IDs will just be different
f.Labels.Select(l => l.Id)
I have made a many to many nav on both Files and Labels
so it'll go either direction
Could I please bug you for the best way to handle the ORs with this? I actually have a list of IDs to OR together and my only thought so far is to do an intersect with an any but I don't know how efficient/well that'd translate.
You could use
.Contains()
Its actually a list of lists of IDs to OR, so I am adding a .Where for each group
Its a list comparison
Wow I feel stupid
haha, thanks
Wow that is.... very fast
Almost feels too fast
Thank you so much @ZZZZZZZZZZZZZZZZZZZZZZZZZ that works extremely well. My old buggy search took 8 seconds to process 430K rows. This takes 700ms! Hopefully that actually is all I needed, and I don't need to come back with a caveat
Three orders of magnitude, that's what I call an improvement lol
... Mostly
Yes, the answer is yes it has helped a lot. For some reason though this SQL is produced when I just do a .Count()
Which takes 8-15 seconds to execute and those strings looks cursed AF
I have a feeling the fact I do a .Skip().Take() for pagination for the main page query helps a lot, but this query is not paginated (gets total result count) and basically kills everything
The final paginated query is derived from this query with one additional filter + the SkipTake
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.