0

I already have a working solution which converts the inclusions to their dot paths in order to support .Include/.ThenInclude. But, EF now allows you to add filters such as .Include(x => x.MyNavigations.Where(predicate)), and the dot path notation is not going to work for that. I'd really like to keep EF-specific dependencies out of my repository implementation, but I'd also love to add filters in my joins wherever possible.

Edit: here is an answer showing how we've been supporting ThenInclude` successfully until now: https://stackoverflow.com/a/58844065/15716642

user15716642
  • 171
  • 1
  • 12
  • The question is unclear because it makes incorrect assumptions. EF is a higher level concept than a low-level single-class repository. It's already generic. A DbContext is already a high-level, multi-entity, disconnected Repository and Unit-of-Work. A DbSet is already a single-entity *generic* Repository. Putting a low-level "generic" repository or most likely DAO on top of a high-level ORM leads to huge problems - and questions like this one – Panagiotis Kanavos Apr 05 '23 at 13:58
  • 1
    Another incorrect assumption is that `Include` affects navigation or generates JOINs. It doesn't. `Include` is used to eagerly load related entities that aren't explicitly specified in an *individual* query. EF will load any related objects or properties that are explicitly specified in the `Select` clause, it doesn't need `Include`. If `JOIN` is needed to do that, EF Core will generate a JOIN. If Split queries are used, even if `Include` is involved, it will still load the correct data without JOINs. – Panagiotis Kanavos Apr 05 '23 at 14:00
  • @PanagiotisKanavos you're suggesting that filtered includes don't filter the result set either in the join or where clause? That'd be interesting considering that it's listed as a performance recommendation in the docs. I'll test it out later, but if that's true I don't really care to support it. Also, please simply answer the question or leave your opinions to yourself. I have had no problems at all using a generic repository pattern like this for every scenario outside of filtered includes, so I'll continue to use it as it's a preference among our architects. – user15716642 Apr 05 '23 at 14:09
  • No, I'm saying what I said. That `Include` controls eager loading, not JOINs. There wouldn't be any need for Include filters otherwise - no need to filter entities that you aren't loading anyway. The common strategy for eager loading is to use JOINs, but that's not the only one. In the past, eager loading used separate queries. Then it used only JOINs. Now, with explicit split query configuration, you can specify how you want to load the related entities – Panagiotis Kanavos Apr 05 '23 at 14:10
  • @PanagiotisKanavos so you're just cluttering the comments with something entirely irrelevant as you understand that we're all talking about filtered includes and way past what the pretense of an include is. Got it. – user15716642 Apr 05 '23 at 14:12
  • Sorry if I'm missing something, but what do you want your callers to do? They pass expressions, you parse those to strings, and you pass those strings to EF? I assumed it to be the other way around. – CodeCaster Apr 05 '23 at 14:41
  • @CodeCaster With EF classic, this newish filter feature would've looked something like `Include(x => x.Dogs.Select(y => y.Puppies.Where(z => z.Color == x.Color))` I want to be able to take something like this and convert it to a syntax EF would recognize and apply navigational filtering to. This example, using Select, works fine up until the where clause bit is added. – user15716642 Apr 05 '23 at 14:57
  • Ah so you have code calling your repo using the old Select/SelectMany syntax for nested includes, and you translate that to Include/ThenInclude and you want to support .Select.Where? – CodeCaster Apr 05 '23 at 14:59
  • @CodeCaster Precisely. I understand it's a weird ask and might be the thing that pushes us over the edge, but if it's at all possible without a tremendous amount of code (you can see that the one I linked requires very minimal code) I'd love to add it and leave everything else alone. – user15716642 Apr 05 '23 at 15:00
  • Aight, but then my answer doesn't apply at all, your question is how to transform that borrowed method into one that does the `.Where()` forwarding as well. Perhaps editing your question to show an example call would help. – CodeCaster Apr 05 '23 at 15:09
  • @CodeCaster Not necessarily. My implementation is a bit different and embarrassingly simplified but the gist of it is that there are a lot of ways to convert an expression to that string dot path notation. But you're almost back at square 1 because the idea behind those implementations is to generate something that ultimately doesn't support filtered includes. – user15716642 Apr 07 '23 at 10:24

0 Answers0