You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Review our LEFT vs. INNER join behavior for Include #29645
When Include is used on a required navigation, we currently generate an INNER join. Since we prune "unneeded" Includes (e.g. because the terminating operator is Count), this leads to #19649, where the following two queries yield different results:
To fix this, we could switch to using LEFT join when the included navigation is required; this would prevent the query filter from affecting which principals are returned, and make the query results the same above.
A more extreme question is why we use INNER join in the first place for Include; since Include isn't supposed to be a filter - only include related entities - it logically corresponds more to a LEFT join. There's an assertion that INNER join is more efficient than LEFT join, but this is something we should investigate more deeply. Note that the relationship is still defined as required, which means that there should never be a principal without a dependent in the database (unless the user misconfigured the model).
A change from INNER to LEFT join would be breaking when the required dependent has a query filter, since Include would start returning principals where no dependent pass the query filter. The more extreme change to always do a LEFT join in principle wouldn't be more breaking (i.e. when there's no query filter), since the relationship is required and there should always be at least one dependent for all principals. Users who misconfigured their model would, however, be broken by this, as principals with no dependents would start getting returned.
Reacted by Denis Kaynar, mukogfb, Hakan Altındiş, Alper Konuralp, chtyce, tanersenel, tugbaoguncmert, Can Cuma Yaman, Eymen Sezen, M.Salih Kızılay and 28 more
Note: INNER JOIN is indeed generally more performant across databases, as it allows more freedom to query planners (e.g. it's commutative); so if we switch to LEFT JOIN, there's a good chance we'll regress performance for some queries, in possible significant ways.
Note: INNER JOIN is indeed generally more performant across databases, as it allows more freedom to query planners (e.g. it's commutative); so if we switch to LEFT JOIN, there's a good chance we'll regress performance for some queries, in possible significant ways.
I think this code can be the worst round trip for the problem
_dbContext.Activities.Include(a => a.Customer).Count();
_dbContext.Activities.Include(a => a.Customer).ToList().Count();
Activity
hakanaltindis commentedon Aug 23, 2023
roji commentedon Aug 23, 2023
IseduardoRezende commentedon Jan 9, 2026
I'm having the same "problem" here, it's a very unexpected and hidden behavior =(
roji commentedon Mar 3, 2026
Note: INNER JOIN is indeed generally more performant across databases, as it allows more freedom to query planners (e.g. it's commutative); so if we switch to LEFT JOIN, there's a good chance we'll regress performance for some queries, in possible significant ways.
IseduardoRezende commentedon Mar 3, 2026
I think this code can be the worst round trip for the problem
_dbContext.Activities.Include(a => a.Customer).Count();
_dbContext.Activities.Include(a => a.Customer).ToList().Count();