-->

的EntityFramework:调用上的IQueryable ToList()与〜11.000的记

2019-09-16 08:30发布

我想通过WCF服务来回报从SQL Express的2008 R2服务器相对大量的记录,通过的EntityFramework 4 WCF客户端。 我的测试表中包含约11.000记录的时刻。 LINQ查询是如此简单:

Database DB = new Database(); // create object context
var retValue = DB.Entities.Persons
        .Include("District")
        .Include("District.City")
        .Include("District.City.State")
        .Include("Nationality")

return retValue.ToList();

这大约需要10秒钟才能完成。

当在SQL Server Managament工作室执行同样的SELECT查询只需要不到1秒。

是否必须在EF慢?

Answer 1:

您的查询并不简单,它包含了很多联接(由于中Include S)更重要的是它可能会返回大量的重复数据,尤其是如果所包含的导航属性集合: https://stackoverflow.com/a/二十七万〇五百九十一分之五百五十二万二千一百九十五

comsuming部分的时间是对象物化以及将所述实体时从数据库中的结果被返回到实体框架上下文的上下文。

这是由您的测量(在评论你的问题)证实,在同一范围内的第二查询是非常快的。 在这种情况下,EF将执行一个查询到数据库,但不需要再兑现的对象,因为它们仍然会附加到上下文。

如果你在第二个方面所得实体必须附加到新的上下文中运行第二个查询 - 这一步又是慢(也是由测量证实)。

这可能是一个点,与EF查询实际上在缓慢而增添了不少的开销相比原始的SQL查询。 EF需要创建更改跟踪和消耗更多的时间范围内管理对象的身份准备了很多数据结构。

我可以看到,以提高性能禁用更改跟踪的唯一方法(假设,你不需要它为您的操作)。 在EF 4.0 / ObjectContext将是:

Database DB = new Database();
DB.Entities.Persons.MergeOption = MergeOption.NoTracking;
// MergeOption is in System.Data.Objects namespace

使用此方法时,一个人必须知道,虽然相关对象将作为单独的对象被创建,即使它们具有相同的关键 - 这是不启用更改跟踪的情况下,因为连接到上下文将避免这种重复。

因此,可能更对象将被加载到内存中。 如果这是适得其反,降低实际更或者它是否仍然执行得更好性能测试的问题。



Answer 2:

这很可能是因为编译查询(LINQ查询W¯¯大量的包括 - > SQL中使用)是EF相比,查询执行速度很慢。 您可以验证这是否是由CPU剖析你的代码的问题。 考虑使用较少的包括多个+较小的查询,使用编译的查询/ IES或升级到最新公测EF5。



文章来源: EntityFramework : Calling ToList() on IQueryable with ~11.000 records takes 10 seconds