C# 使用实体框架检索多个嵌套实体的性能较慢

C# 使用实体框架检索多个嵌套实体的性能较慢,c#,sql,sql-server,entity-framework,lazy-loading,C#,Sql,Sql Server,Entity Framework,Lazy Loading,我使用EntityFramework6来检索一个实体,该实体具有多个到深度嵌套实体的导航属性。我正面临着巨大的性能影响,记录实体框架的请求已经大大提高了性能。我最深的实体(Geocoordinate)中有数百条记录,检索会话实体最多需要8秒(我希望不到1秒) 以下是日志的主要示例: 这是我的密码: using (var context = new ModelContainer()) { context.Database.Log = msg

我使用EntityFramework6来检索一个实体,该实体具有多个到深度嵌套实体的导航属性。我正面临着巨大的性能影响,记录实体框架的请求已经大大提高了性能。我最深的实体(Geocoordinate)中有数百条记录,检索会话实体最多需要8秒(我希望不到1秒)

以下是日志的主要示例:

这是我的密码:

        using (var context = new ModelContainer())
        {
            context.Database.Log = msg => Trace.WriteLine(msg);
            var session= await
                context.SessionSet.FirstOrDefaultAsync(a => a.Identifier == sessionIdentifier);
            var result = await Json(session).ExecuteAsync(new CancellationToken());
            return ResponseMessage(result);
        }
我正在检索模型中的红色实体(请注意路由和地理位置之间唯一的一对多关系):

(链接到大尺寸图像:)


我曾尝试禁用延迟加载并使用Include立即加载我的实体,但更糟糕的是,我已达到SQL Server超时。

加载实体花费如此长时间的原因是您遇到了典型的选择N+1问题

正如您已经知道的,默认情况下,EntityFramework通过在导航属性周围创建动态代理对象来加载所有导航属性。如果它检测到代理被访问(即,您遵循navigation属性),那么它会向数据库发出一个查询,以实际启动并获取数据。这会对性能产生影响的原因是,执行的每个数据库查询都有一定的开销(例如,数据库服务器的延迟),因此最好的选择是执行一个查询,一次性返回您需要的所有数据,而不是对每个实体进行单独的查询

当涉及到集合属性(例如,您的
Route->Geoposition
关系)时,情况会变得更糟,因为实体框架将为集合中的每个项目生成单独的选择。这就是为什么您在日志中看到如此多的查询

我已尝试禁用延迟加载,并使用Include加载我的 但更糟糕的是,我已经达到SQL Server超时


使用
Include
方法是在初始查询中急切加载导航属性的正确方法。如果在
包含
相关导航属性之后,仍然发现查询执行时间过长,则应查看查询的执行计划,以了解性能问题所在。如果您需要帮助分析,请发布另一个问题。

您确定这是EF的问题吗?我的意思是,如果你运行类似的TSQL查询,它运行得更快吗?不,差不多一样。。。我认为我的模型没有真正优化。我会简化一些关系,然后性能会更好。这解决了我的问题,谢谢!急于加载有问题的实体是关键。