Ich benutze EF Core in einem asp.net MVC Core 1.1.0 Projekt und haben eine ziemlich komplexe Abfrage.EF Core mehrere Links Joins
_context
.Profiles
.Include(p => p.Blog)
.ThenInclude(b => b.Network)
.Include(p => p.Blog)
.ThenInclude(i => i.AgeDistributions)
.ThenInclude(i => i.AgeRange)
.Include(p => p.Blog)
.ThenInclude(b => b.GenderDistributions)
.Include(p => p.Instagram)
.ThenInclude(i => i.Network)
.Include(p => p.Instagram)
.ThenInclude(i => i.AgeDistributions)
.ThenInclude(i => i.AgeRange)
.Include(p => p.Instagram)
.ThenInclude(b => b.GenderDistributions)
.Include(p => p.Youtube)
.ThenInclude(y => y.Network)
.Include(p => p.Youtube)
.ThenInclude(i => i.AgeDistributions)
.ThenInclude(i => i.AgeRange)
.Include(p => p.Youtube)
.ThenInclude(b => b.GenderDistributions)
.Include(p => p.Snapchat)
.ThenInclude(s => s.Network)
.Include(p => p.Musically)
.Include(p => p.ProfileCategories)
.ThenInclude(pc => pc.Category)
.Include(p => p.Tags)
.ThenInclude(tag => tag.Tag)
.Where(p => !p.Deleted);
Jede soziale Plattform kann jede Art von Statistik haben. Zum Beispiel werden AgeDistributions
mit einer Basisklasse modelliert, die eine PlatformId
hat und jede abgeleitete {Platform}AgeDistribution
spezifiziert die Navigationseigenschaft, um Fremdschlüssel richtig einzurichten.
public class AgeInterval {
public int Id { get; set; }
// At most five length. -18, 18-24, ..., 65-
public string Interval { get; set; }
}
public class PlatformAgeStatistics {
public int PlatformId { get; set; }
public int IntervalId { get; set; }
public AgeInterval Interval { get; set; }
public decimal Distribution { get; set; }
}
public class InstagramAgeStatistics : PlatformAgeStatistics {
[ForeignKey("PlatformId")]
public Instagram Platform { get; set; } //
}
Above Abfrage manchmal sehr lange Zeit (db Ausführungs-Timeout nach 30 Sekunden) und Inspektion der SQL ich denken entweder ich habe eine Modellierung Problem, dass EF nicht korrekt ermitteln oder EF ist nur suboptimal SQL zu generieren. Die Ergebnismenge wird mithilfe von skip und take paginiert und das Abrufen von zehn Datensätzen dauert zeitaufwendig.
Dies ist die erste SQL, die
SELECT -- Emitted
FROM [Profiles] AS [p]
LEFT JOIN [BlogChannels] AS [b] ON [b].[ProfileId] = [p].[Id]
LEFT JOIN [InstagramChannels] AS [i] ON [i].[ProfileId] = [p].[Id]
LEFT JOIN [YoutubeChannels] AS [y] ON [y].[ProfileId] = [p].[Id]
LEFT JOIN [BlogChannels] AS [b2] ON [b2].[ProfileId] = [p].[Id]
LEFT JOIN [InstagramChannels] AS [i2] ON [i2].[ProfileId] = [p].[Id]
LEFT JOIN [YoutubeChannels] AS [y2] ON [y2].[ProfileId] = [p].[Id]
LEFT JOIN [BlogChannels] AS [b4] ON [b4].[ProfileId] = [p].[Id]
LEFT JOIN [Networks] AS [n] ON [b4].[NetworkId] = [n].[Id]
LEFT JOIN [InstagramChannels] AS [i4] ON [i4].[ProfileId] = [p].[Id]
LEFT JOIN [Networks] AS [n0] ON [i4].[NetworkId] = [n0].[Id]
LEFT JOIN [YoutubeChannels] AS [y4] ON [y4].[ProfileId] = [p].[Id]
LEFT JOIN [Networks] AS [n1] ON [y4].[NetworkId] = [n1].[Id]
LEFT JOIN [SnapchatChannels] AS [s] ON [s].[ProfileId] = [p].[Id]
LEFT JOIN [Networks] AS [n2] ON [s].[NetworkId] = [n2].[Id]
LEFT JOIN [MusicallyChannels] AS [m] ON [m].[ProfileId] = [p].[Id]
WHERE [p].[Deleted] = 0
ORDER BY [p].[FullName], [p].[Id], [b].[Id], [i].[Id], [y].[Id], [b2].[Id], [i2].[Id], [y2].[Id]
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY
Dann mehrere Abfragen folgt ausgeführt wird, die nicht ganz sieht rechts
SELECT [y3].[Gender], [y3].[ChannelId], [y3].[Distribution]
FROM [YoutubeGenderDistribution] AS [y3]
INNER JOIN (
SELECT DISTINCT [t7].*
FROM (
SELECT [p].[FullName], [p].[Id], [b].[Id] AS [Id0], [i].[Id] AS [Id1], [y].[Id] AS [Id2], [b2].[Id] AS [Id3], [i2].[Id] AS [Id4], [y2].[Id] AS [Id5]
FROM [Profiles] AS [p]
LEFT JOIN [BlogChannels] AS [b] ON [b].[ProfileId] = [p].[Id]
LEFT JOIN [InstagramChannels] AS [i] ON [i].[ProfileId] = [p].[Id]
LEFT JOIN [YoutubeChannels] AS [y] ON [y].[ProfileId] = [p].[Id]
LEFT JOIN [BlogChannels] AS [b2] ON [b2].[ProfileId] = [p].[Id]
LEFT JOIN [InstagramChannels] AS [i2] ON [i2].[ProfileId] = [p].[Id]
LEFT JOIN [YoutubeChannels] AS [y2] ON [y2].[ProfileId] = [p].[Id]
WHERE [p].[Deleted] = 0
ORDER BY [p].[FullName], [p].[Id], [b].[Id], [i].[Id], [y].[Id], [b2].[Id], [i2].[Id], [y2].[Id]
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY
) AS [t7]
) AS [y20] ON [y3].[ChannelId] = [y20].[Id5]
ORDER BY [y20].[FullName], [y20].[Id], [y20].[Id0], [y20].[Id1], [y20].[Id2], [y20].[Id3], [y20].[Id4], [y20].[Id5]
eine andere, die "schaut" richtiger
SELECT [b0].[AgeRangeId], [b0].[ChannelId], [b0].[Distribution], [a].[Id], [a].[Range]
FROM [BlogAgeDistribution] AS [b0]
INNER JOIN (
SELECT DISTINCT [t2].*
FROM (
SELECT [p].[FullName], [p].[Id], [b].[Id] AS [Id0]
FROM [Profiles] AS [p]
LEFT JOIN [BlogChannels] AS [b] ON [b].[ProfileId] = [p].[Id]
WHERE [p].[Deleted] = 0
ORDER BY [p].[FullName], [p].[Id], [b].[Id]
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY
) AS [t2]
) AS [b1] ON [b0].[ChannelId] = [b1].[Id0]
LEFT JOIN [AgeRanges] AS [a] ON [b0].[AgeRangeId] = [a].[Id]
ORDER BY [b1].[FullName], [b1].[Id], [b1].[Id0]
Eine Idee, warum EF alle anderen Plattformen bei der Anforderung der Statistiken für zB verbindet Instagram
.
Danke!
Edit:
Interessanterweise ist die erste Abfrage für Age
ein mit allen drei
SELECT [y0].[AgeRangeId], [y0].[ChannelId], [y0].[Distribution], [a1].[Id], [a1].[Range]
FROM [YoutubeAgeDistribution] AS [y0]
INNER JOIN (
SELECT DISTINCT [t4].*
FROM (
SELECT [p].[FullName], [p].[Id], [b].[Id] AS [Id0], [i].[Id] AS [Id1], [y].[Id] AS [Id2]
FROM [Profiles] AS [p]
LEFT JOIN [BlogChannels] AS [b] ON [b].[ProfileId] = [p].[Id]
LEFT JOIN [InstagramChannels] AS [i] ON [i].[ProfileId] = [p].[Id]
LEFT JOIN [YoutubeChannels] AS [y] ON [y].[ProfileId] = [p].[Id]
WHERE [p].[Deleted] = 0
ORDER BY [p].[FullName], [p].[Id], [b].[Id], [i].[Id], [y].[Id]
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY
) AS [t4]
) AS [y1] ON [y0].[ChannelId] = [y1].[Id2]
LEFT JOIN [AgeRanges] AS [a1] ON [y0].[AgeRangeId] = [a1].[Id]
ORDER BY [y1].[FullName], [y1].[Id], [y1].[Id0], [y1].[Id1], [y1].[Id2]