【发布时间】:2020-05-27 13:09:02
【问题描述】:
我正在将我的 Java 应用程序移植到 C# 并发现 Entity Framework 在实例化对象时似乎真的很慢。
首先,关于正在使用的版本的一些细节:
- VS 2019
- .NET Framework 4.7.2
- EF 6
- MySQL 8.0.20
由于我要移植我的应用程序,因此我使用了 DB First 方法。
现在,我有一个包含大约 2000 个条目的表,完全独立,没有什么特别之处。在 Java 中,我手动读取表格并实例化类,这需要大约 30 毫秒 - 仍然非常慢,但足够好。在 EF 中,这需要一秒钟...
有问题的行是:
// _baat2db is my DBContext
_baatc2db.dbexchanges.ToList();
这条线总是需要一秒钟才能完成。
Using Interceptors,我记录了生成的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
所以读取表格数据需要 3ms,这是人们所期望的。这也让我得出结论,花费这么长时间的东西与数据库或数据库连接无关,而是在处理返回的数据的过程中,可能是在实例化对象时。
表字段及其映射为INT -> int、VARCHAR -> string 和BIT -> bool。一个是Nullable,两个具有在生成的构造函数中设置的默认值。
有什么想法吗?有什么我应该看的吗?我该怎么做才能进一步调试问题?
谢谢!
更新:
作为D Stanley suggested,在第二次调用(20-25ms)时表现良好。
仍然很难理解为什么第一次需要 1 秒的时间,因为我之前打开了连接。例如。以下测试:
_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
【问题讨论】:
-
每次都需要一秒钟吗?通常,像这样的流程会产生巨大的启动成本(建立连接等),这可能会导致单次运行的结果出现偏差。e 如果您循环并创建列表 10 次会怎样?
-
@DStanley 非常好!是的,它第二次按预期运行(20 毫秒)!。这仍然有点难以理解(1 秒真的很长),因为即使我在 5 秒前执行
Thread.Sleep以确保程序中的其他所有内容都处于空闲状态,它也需要超过 1 秒。我之前也手动打开了连接,所以在这个测试中,连接也已经持续了 5 秒。 -
最好使用 .NET Core 和 EF Core,因为 .NET Framework 已弃用且 EF 6 不再维护。
-
它可能不仅仅是连接 - 它可能是 EF 类中的其他设置(构建元数据等)。
-
@IanKemp 谢谢!是的,这些步骤确实有帮助,因此回答了我的问题。首先,EFInteractiveViews 缓存将加载时间减少到 500 毫秒,然后using ngen to precompile Entity Framework 将加载时间减少到 90 毫秒左右。
标签: c# .net entity-framework-6