I'm porting my Java application to C# and discovered that Entity Framework seems to be really slow when instantiating objects.
First, some details about the versions in use:
- VS 2019
- .NET Framework 4.7.2
- EF 6
- MySQL 8.0.20
Since I'm porting my application, I used DB First approach.
Now, I've a table with roughly 2000 entries, completely self-contained, nothing special about it. In Java, I manually read in the table and instantiated classes which took around 30ms - still super slow, but good enough. In EF, this takes over a second...
The line in question is:
// _baat2db is my DBContext
_baatc2db.dbexchanges.ToList();
This line always takes over a second to complete.
Using Interceptors, I logged the generated SQL:
SELECT
`Extent1`.`exchangeId`,
`Extent1`.`mic`,
`Extent1`.`country`,
`Extent1`.`city`,
`Extent1`.`timeZoneId`,
`Extent1`.`countryIsoCode`,
`Extent1`.`operatingMic`,
`Extent1`.`institution`,
`Extent1`.`acronym`,
`Extent1`.`website`,
`Extent1`.`statusDate`,
`Extent1`.`creationDate`,
`Extent1`.`comment`,
`Extent1`.`isOperating`,
`Extent1`.`isActive`,
`Extent1`.`calendarId`
FROM `dbexchange` AS `Extent1`
-- Executing at 27.05.2020 14:16:42 +02:00
-- Completed in 3 ms with result: EFMySqlDataReader
So it takes 3ms to read the table data, which is what one would expect. This also leads me to the conclusion that whatever takes so long is not related to the database or the database connection, but rather in the process of processing the returned data, probably when instantiating the objects.
The table fields and their mappings are INT -> int
, VARCHAR -> string
and BIT -> bool
. One is Nullable
, two have default values that get set in the generated constructor.
Any ideas what's wrong here? Anything that I should take a look into? What can I do, to further debug the issue?
Thanks!
Update:
As D Stanley suggested, it performs well when calling it a second time (20-25ms).
It's still hard to understand why it takes the eternity of 1 second the first time, since I open the connection before. E.g. following test:
_baatc2db.Database.Connection.Open();
// now, after after StateChange to ConnectionState.Open:
Thread.Sleep(5000);
_baatc2db.dbexchanges.ToList(); // 1+ second
Thread.Sleep(5000);
_baatc2db.dbexchanges.ToList(); // 20-25ms