-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EF Core explicit loading query with owned type collection causes cartesian explosion error #32876
Comments
Note from triage: avoid generating the warning when EF is creating the query. |
Note that the warning/exception is correct and should be generated. When the latter query is allowed to generate & run, this is what it looks like: SELECT [t].[Id], [t].[Category], [c].[Id], [t].[CustomerId], [t].[OrderedProductsId], [t0].[CustomerId], [t0].[OrderedProductsId], [t0].[Id], [t0].[CustomerId0], [t0].[Id0], [t0].[Name]
FROM [Customers] AS [c]
INNER JOIN (
SELECT [p].[Id], [p].[Category], [c0].[CustomerId], [c0].[OrderedProductsId]
FROM [CustomerProduct] AS [c0]
INNER JOIN [Products] AS [p] ON [c0].[OrderedProductsId] = [p].[Id]
) AS [t] ON [c].[Id] = [t].[CustomerId]
LEFT JOIN (
SELECT [c1].[CustomerId], [c1].[OrderedProductsId], [c2].[Id], [c3].[CustomerId] AS [CustomerId0], [c3].[Id] AS [Id0], [c3].[Name]
FROM [CustomerProduct] AS [c1]
INNER JOIN [Customers] AS [c2] ON [c1].[CustomerId] = [c2].[Id]
LEFT JOIN [Contact] AS [c3] ON [c2].[Id] = [c3].[CustomerId]
WHERE [c2].[Id] = @__p_0
) AS [t0] ON [t].[Id] = [t0].[OrderedProductsId]
WHERE [c].[Id] = @__p_0
ORDER BY [c].[Id], [t].[CustomerId], [t].[OrderedProductsId], [t].[Id], [t0].[CustomerId], [t0].[OrderedProductsId], [t0].[Id], [t0].[CustomerId0] As you see, both the products and the contacts are queried (with strange redundancies BTW), making the query "explode". It seems to me that explicitly loading a collection should only query that collection. |
I'm confused... is this a bug or "type-enhancement"? (I'm not being sarcastic - I don't know. I assumed it was a bug.) If it's not a bug (i.e. problem is in our code), how should we handle such cases? |
We generate the warning so that the developer can choose to use split-queries if appropriate. For queries that we generate internally, the user doesn't have the option to do that, so it doesn't make sense to generate the warning. I guess this could be a bug that we shouldn't generate the warning, but since it is strictly true, just not helpful, it would just be better to not generate it. |
Thanks, understood. So is there no good workaround other than "just ignore the warning till v9 / November"? |
@lonix1 Can you explain a bit more why you need a workaround? |
Because we get the typical "You have not defined query splitting behaviour... visit this link for info" warning during runtime. |
@lonix1 As a workaround, disable the warning. |
That works. But (like mentioned above) it would be disabled globally - so it would not detect real cases of this problem. It's a very useful warning, saved me many times. So there doesn't seem to be a workaround. |
@lonix1 Typically, a workaround is something that is not a perfect fix. If you really don't want the warning, then you can either use our query as a starting point or write your own query to do the loading. |
A workaround for anyone who needs it: builder.Entity<Customer>().Navigation(x => x.Contacts).AutoInclude(false); That prevents EF from automatically loading that owned type collection, which prevents the warning from being shown for this specific entity, but does not change that behaviour for others. That warning is very useful, it's best not to disable it globally. Of course that introduces a new problem, in that one must manually load the collection whenever needed, e.g. await context.Customers.Include(x => x.Contacts).ToListAsync(); Hopefully we can get a fix before November/v9. |
I'm actually not sure that this is the intended behavior - according to the general design around owned entities, it shouldn't be possible to not load one when its parent is loaded... /cc @ajcvickers
That's quite unlikely, as there isn't an actual bug here. |
Right, but, as with almost anything, that can be overridden, since it just an auto-include by convention. I certainly wouldn't do it, but not sure we should block it. @AndriySvyryd? |
Can we return to the root problem? There is a loaded entity object |
@GertArnold When you load an an entity with owned types, the owned types are always also loaded. That's a big part of what owned types are. This means that when loading entities on the other end of a relationship, the owned types for those entities are loaded also. This is by design. |
Maybe I'm missing something, but the explicit load action is expected to load |
@GertArnold Ah, I see what you are saying. I think you are right. I'll file a new issue for that. |
Handling auto-included members such as properties, complex properties and owned types will be enabled by #1387 |
.NET 7.0.405
EF Core version: 7
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL 7.0.4
Target framework: .NET 7
Operating system: linux
IDE: vscode
I have an EF Core entity with a collection of owned entities (
Customer.Contacts
) and a collection of regular entities (Customer.OrderedProducts
).When I load data using "explicit loading", I get a "cartesian explosion" error.
A complete minimal reproduction follows (for .NET 7).
Model.cs
:Program.cs
:Error:
The error is the one expected for a query with multiple
.Include(x => x.Foos).Include(x => x.Bars)
, which leads to "Cartesian Explosion". The solution in those cases is to use AsSplitQuery(). I don't see how that applies in this case.When I remove the owned type collection, it works as expected.
Is this a bug in my code or in EF?
(I know I can ignore the warning, but I don't want to do that. It is useful for detecting ACTUAL cartesian explosion issues elsewhere in my code.)
UPDATE:
I also posted on SO without resolution, so I assume this is a bug. If so, is there a workaround where I can continue to rely on "MultipleCollectionIncludeWarning" to detect cartesian explosion in my code, but disable it for this particular false positive?
The text was updated successfully, but these errors were encountered: