I have a case of a poorly generated query.
This is related to OData but I'm guessing that it's probably EF that is the culprit but as I am not sure I decided to include OData as well.
Update: Based on the test suggested by Svyatoslav, it seems like it's OData that is adding the extra joins.
In my client that is consuming the OData endpoint I do the following:
container
.Betaling
.Expand(l => l.Udsendelser)
.Expand(l => l.Kvitteringer)
.Where(...)
Now I know this can be rather slow in itself but it's actually a lot slower than it has to be in my opinion.
When looking in sql profiler the following script is the sql that is generated.
Most columns have been removed or replaced by * to make it easier to read.
SELECT [b0].[Betalingsid]
,[b0].[Id]
,[b0].[ModtagetDatoTid]
,CAST([b0].[Status] AS int)
,[b1].[Betalingsid]
,[b1].[Id]
,[b1].[OprettetDatoTid]
,CAST([b1].[Status] AS int)
,[b2].[Betalingsid]
,[b2].[Id]
,[b2].[OprettetDatoTid]
,CAST([b2].[Status] AS int)
,[b3].[Betalingsid]
,[b3].[Id]
,[b3].[ModtagetDatoTid]
,CAST([b3].[Status] AS int)
FROM
(
SELECT TOP (17) *
FROM [BetalingView] AS [b]
WHERE ((CAST([b].[Status] AS int) = 8) OR (CAST([b].[Status] AS int) = 7)) OR
(CAST([b].[Status] AS int) = 11)
ORDER BY [b].[Id] DESC
) AS [t]
LEFT JOIN [BetalingUdsendelseView] AS [b0] ON [t].[Id] = [b0].[Betalingsid]
LEFT JOIN [BetalingKvitteringView] AS [b1] ON [t].[Id] = [b1].[Betalingsid]
LEFT JOIN [BetalingKvitteringView] AS [b2] ON [t].[Id] = [b2].[Betalingsid]
LEFT JOIN [BetalingUdsendelseView] AS [b3] ON [t].[Id] = [b3].[Betalingsid]
ORDER BY [t].[Id] DESC, [b0].[Id], [b1].[Id], [b2].[Id], [b3].[Id]
Now in my opinion 2 of those joins shouldn't be needed to get the required result.
In some of the most extreme cases this query gets about 600.000 rows but the actual data should be closer to 1600 rows.
The following is my EF configuration (partial):
public void Configure(EntityTypeBuilder<BetalingView> builder)
{
builder
.ToView("BetalingView");
builder
.HasKey(e => e.Id);
builder
.HasMany(b => b.Udsendelser)
.WithOne()
.HasForeignKey(u => u.Betalingsid);
builder
.HasMany(b => b.Kvitteringer)
.WithOne()
.HasForeignKey(u => u.Betalingsid);
}
public void Configure(EntityTypeBuilder<BetalingUdsendelseView> builder)
{
builder
.ToView("BetalingUdsendelseView");
builder
.HasKey(e => e.Id);
}
public void Configure(EntityTypeBuilder<BetalingKvitteringView> builder)
{
builder
.ToView("BetalingKvitteringView");
builder
.HasKey(e => e.Id);
}
Is this just EF being crappy at generating queries or am i missing something in my configuration?
Could it be OData playing some trick with the query somehow?
Don't hesitate to ask if you need more info.
Also i apologize for the lengthy post.
So I found the issue.
It was a combination of OData and AutoMapper as both of them added the joins.
My only solution was to prohibit the use of Expand and then always load the related entities.