This question already has an answer here:
Is it always better to use 'DbContext' instead of 'ObjectContext'?
(1个答案)
7年前关闭。
最近,我将实体模型从使用4.1的ObjectContext迁移到使用5.0的DbContext。我开始后悔这样做,因为我注意到使用DbContext vs ObjectContext的查询性能很差。这是测试场景:
这两个上下文使用具有大约600个表的同一数据库。 LazyLoading和ProxyCreation都关闭了(代码示例中未显示)。两者都有预先生成的 View 。
该测试首先进行1次调用以加载元数据工作空间。然后在一个执行了100次的for循环中,我创建了一个上下文并进行了一个调用,该调用的第一个调用为10。(我正在for循环内创建该上下文,因为这模拟了WCF服务中使用的情况,这会创建一个每次上下文)
当我使用ObjectContext运行它时,大约需要4.5秒。当我使用DbContext运行它时,大约需要17秒。我使用RedGate的性能分析器对此进行了分析。对于DbContext来说,罪魁祸首似乎是称为UpdateEntitySetMappings的方法。在每个查询中都会调用此方法,它似乎是在检索元数据工作空间并在OSpace中的每个项目之间循环。 AsNoTracking没有帮助。
编辑:为了提供更好的详细信息,问题与DbSet与ObjectSet的创建\初始化有关,而不与实际查询有关。当我使用ObjectContext进行调用时,创建ObjectSet平均需要42毫秒。当我使用DbContext进行调用时,创建内部dbset大约需要140毫秒。 ObjectSet和DbSet都从元数据工作空间中进行一些实体集映射查找。我注意到的是DbSet可以为工作空间中的所有类型执行此操作,而ObjectSet则不可以。我猜(没有尝试过)一个具有较少表的模型,其性能差异较小。 您检索的记录越多, 的差异就越少您检索到的记录越多,如果您想提高速度,就要关闭跟踪
例如,仅检索10条记录
请注意,代码优先比模型优先慢得多,并且跟踪与不跟踪之间没有明显的区别-两种观察都与您的观察完全一样。
但是,当检索10000行时
请注意,在notracking版本中,代码优先和模型优先之间几乎没有区别。而且,两者的性能都出乎意料的好,几乎与原始ado.net数据读取器一样快。
请关注我的博客条目以获取更多详细信息。
这个简单的基准帮助我首先接受了代码的本质。对于两个小型项目,我仍然更喜欢它,因为它具有两个功能:poco实体和迁移。另一方面,对于性能是关键要求的项目,我永远不会选择两者中的任何一个。这实际上意味着我可能永远不会再使用模型优先方法。
(附带说明:我的基准测试还显示nHibernate出了点问题。即使我已咨询过每天使用NH的两个独立开发人员,我仍然找不到任何人来帮助我解释这一点)
(1个答案)
7年前关闭。
最近,我将实体模型从使用4.1的ObjectContext迁移到使用5.0的DbContext。我开始后悔这样做,因为我注意到使用DbContext vs ObjectContext的查询性能很差。这是测试场景:
这两个上下文使用具有大约600个表的同一数据库。 LazyLoading和ProxyCreation都关闭了(代码示例中未显示)。两者都有预先生成的 View 。
该测试首先进行1次调用以加载元数据工作空间。然后在一个执行了100次的for循环中,我创建了一个上下文并进行了一个调用,该调用的第一个调用为10。(我正在for循环内创建该上下文,因为这模拟了WCF服务中使用的情况,这会创建一个每次上下文)
for (int i = 0; i < 100; i++)
{
using (MyEntities db = new MyEntities())
{
var a = db.MyObject.Take(10).ToList();
}
}
当我使用ObjectContext运行它时,大约需要4.5秒。当我使用DbContext运行它时,大约需要17秒。我使用RedGate的性能分析器对此进行了分析。对于DbContext来说,罪魁祸首似乎是称为UpdateEntitySetMappings的方法。在每个查询中都会调用此方法,它似乎是在检索元数据工作空间并在OSpace中的每个项目之间循环。 AsNoTracking没有帮助。
编辑:为了提供更好的详细信息,问题与DbSet与ObjectSet的创建\初始化有关,而不与实际查询有关。当我使用ObjectContext进行调用时,创建ObjectSet平均需要42毫秒。当我使用DbContext进行调用时,创建内部dbset大约需要140毫秒。 ObjectSet和DbSet都从元数据工作空间中进行一些实体集映射查找。我注意到的是DbSet可以为工作空间中的所有类型执行此操作,而ObjectSet则不可以。我猜(没有尝试过)一个具有较少表的模型,其性能差异较小。
最佳答案
我还担心代码优先方法的性能不佳,并且在与您类似的情况下执行了一些基准测试
http://netpl.blogspot.com/2013/05/yet-another-orm-micro-benchmark-part-23_15.html
结果并不出人意料,因为DbContext是ObjectContext的包装,所以为简单起见,它不得不牺牲性能。但是,我的测试表明:
例如,仅检索10条记录
请注意,代码优先比模型优先慢得多,并且跟踪与不跟踪之间没有明显的区别-两种观察都与您的观察完全一样。
但是,当检索10000行时
请注意,在notracking版本中,代码优先和模型优先之间几乎没有区别。而且,两者的性能都出乎意料的好,几乎与原始ado.net数据读取器一样快。
请关注我的博客条目以获取更多详细信息。
这个简单的基准帮助我首先接受了代码的本质。对于两个小型项目,我仍然更喜欢它,因为它具有两个功能:poco实体和迁移。另一方面,对于性能是关键要求的项目,我永远不会选择两者中的任何一个。这实际上意味着我可能永远不会再使用模型优先方法。
(附带说明:我的基准测试还显示nHibernate出了点问题。即使我已咨询过每天使用NH的两个独立开发人员,我仍然找不到任何人来帮助我解释这一点)
关于c# - 相对于ObjectContext,DbContext查询性能较差,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15589520/
10-16 09:03