Add an IncludeInner method
See original GitHub issueThe relational database model doesn’t have a concept of mandatory children since ownership is defined by a foreign key in a child relation. As a consequence, in SQL, Include
always has to translate to OUTER JOIN
because there’s no formal language to configure the association as 1-1..n
(certainly not vendor-independent). It’s always 1-0..n
. A statement like
context.Parents.Include(p => p.Children)
should, of course, return all parent records, not just the ones with children. Hence the outer join.
There are three reasons why this OUTER JOIN
may not always be desired.
- It’s not uncommon for parents without children to be invalid or meaningless. Fetching them from the database by plain SQL would always involve an
INNER JOIN
because there is foreknowledge of the database content. (Which in such cases will be enforced by client-side validation). - Irrespective of database content, developers may want to
Include
children and at the same time filter only parents with children. Here,INNER JOIN
is better thanOUTER JOIN
+ a predicate. Again, in plain SQL that would be a no-brainer. INNER JOIN
s may perform significantly better thanOUTER JOIN
s, esp. in more complex queries, it would be useful for developers to have control over the type of join EF will execute.
So I wonder if there is a case for adding an IncludeInner
(+ ThenIncludeInner
) method that does exactly that: always translate to an inner join?
This will also work with filtered includes. It can also be made to work with split queries: one query without results for a parent will remove the parent from the end result.
It is expected from developers to have sufficient knowledge of SQL to understand how INNER
and OUTER
joins work an how they affect one another, esp. how one INNER JOIN
can turn previous OUTER JOIN
s into de-facto INNER
joins.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:6
- Comments:10 (4 by maintainers)
I have to upvote the original suggestion and disagree with the idea that optional/required metadata should decide whether inner or outer joins should be used. You don’t define foreign keys as an “inner foreign keys” or “outer foreign keys”. Foreign keys are supposed to allow you to write both inner and outer joins depending on the scenario. Currently you have to write complex LINQ queries to get an inner join on a many to many relationship. Whereas if you were writing raw SQL you would just have to replace a single keyword with LEFT or INNER.
Instead of going into pattern matching, we could have metadata API to configure that collection will always have 1 child. Just like how we have API to market that principal to dependent reference navigation is required. (i.e. Child will always exist for the given principal). This will be useful for any nav expansion not just include.
Apart from that, users are free to write LINQ when their joins contain additional information not configured in metadata manually using existing LINQ operators to generate inner/outer join as needed.