I have a POCO class with a lazy-loaded collection, which currently takes 10 seconds to load, with about 10.000 entries; using Entity Framework 6.3 and SQL Server 2016.
I realize that loading 10.000 entries takes some time, and perhaps these times are to be expected. But I cannot figure out where the time is actually spent.
I know I can disable lazy-loading. But right now I simply want to understand this problem better. How can I see where the time is lost, and which exact SQL statements take a long time, or are executed too often?
Loading the property, e.g. via Console.WriteLine(parent.Children.First().ID) takes 10 seconds.
If I enable logging via dbContext.Database.Log = s => Console.WriteLine(s);, I only see a single SQL command:
SELECT
[Extent1].[Foo] AS [Foo], ...
[Extent1].[Parent_ID] AS [Parent_ID],
FROM [dbo].[Child] AS [Extent1]
WHERE [Extent1].[Parent_ID] = @EntityKeyValue1
-- Completed in 1 ms with result: SqlDataReader
The command completes in a millisecond. There do not appear to be 10.000 follow-up SQL commands that would explain the long loading times.
When I query the database in SQL Management Studio, I get similar times: displaying all 10.000 rows takes only a few milliseconds.
I implemented a DbCommandInterceptor, to find any long-running or repeated sql commands I may have missed, but found nothing either.
The property is configured like this:
public class Parent {
...
public virtual ICollection<Children> Children { get; set; }
}
public class Child {
...
public int Parent_ID { get; set; }
public virtual Parent Parent{ get; set; }
}
...
modelBuilder.Entity<Child>()
.HasRequired(a => a.Parent)
.WithMany(b => b.Children)
.HasForeignKey(c => c.Parent_ID)
.WillCascadeOnDelete(false);
The database table "child" used for testing contains only the 10.000 rows that should be returned by the lazy-loaded property, and no other rows with any other foreign key.