Say*_*Pal 25 entity-framework query-performance ef-code-first
我已经认识到这一概念AsNoTracking(),DetectChanges()以及AutoDetectChangesEnabled最近.据我所知,当使用Entity Framework从数据库中获取记录时AsNoTracking(),实体框架不会跟踪这些记录的任何更改,在这种情况下更新获取记录的任何属性都将失败.
我的问题是,如果以这种方式获取记录,它是否也会导致禁用对DetectChanges()的自动调用,或者是否必须通过设置显式完成:
Context.Configuration.AutoDetectChangesEnabled = false;
Run Code Online (Sandbox Code Playgroud)
另请告诉我,如果在为了只读的目的而严格获取数据时执行这两个操作,它会产生什么影响(在性能方面):
Context.Configuration.AutoDetectChangesEnabled = false;
Context.Set<T>().AsNoTracking();
Run Code Online (Sandbox Code Playgroud)
Ger*_*old 31
它还会导致禁用自动调用DetectChanges()
不,不会.但你必须意识到这一点AsNoTracking并且DetectChanges彼此无关(除了成为EF的一部分).AsNoTracking无论是否启用AutoDetectChanges,无论如何都将检测到的对象将永远不会被检测到.此外,AsNoTracking在一个DbSet层面上,AutoDetectChangesEnabled在上下文层面上工作.让DbSet方法影响整个上下文会很糟糕.
或者[设置
AutoDetectChangesEnabled]必须明确地完成
好吧,你可能不应该禁用AutoDetectChanges.如果你这样做,你必须知道你做了什么.
如果两个动作都被执行,它会产生什么影响(在性能方面)
如上所述,它们并不相关.它们都可以以自己的方式提高性能.
AsNoTracking如果你想获取只读数据是很好的.它没有副作用(如:效果很明显)设置会AutoDetectChangesEnabled = false停止自动调用DetectChanges(可能很多),但它有副作用,需要注意.来自Lerman&Miller的书DbContext:
需要调用DetectChanges时的工作并不像它可能出现的那样微不足道.实体框架团队强烈建议您在遇到性能问题时仅交换手动调用DetectChanges.还建议仅针对性能较差的代码段选择退出自动DetectChanges,并在有问题的部分完成执行后重新启用它.
Ter*_*tta 20
我们发现设置AutoDetectChangesEnabled = false可能会产生大量(即10倍)性能影响.
背景:我们的系统完全由使用变化检测代理的EF模型对象组成.也就是说,我们所有的DB字段和关系属性都被声明为虚拟.我们还有一个相对深度结构化的对象模型.那就是对象A包含一组对象B,它又包含一组对象C等.我们观察到通过EF/LINQ查询实例化这些对象的非平凡(> 100)是很昂贵的.例如,在一种情况下,实例化250个对象需要大约2秒.我们还观察到实例化相同的结构,但使用匿名对象需要大约25毫秒.最后,我们观察到,如果我们设置AutoDetectChangesEnabled = false,我们可以使用查询实例化EF模型对象并再次实现约25毫秒.
所以,至少对我们来说,通过设置它是错误的,可以获得巨大的收益.我们使用工作单元模式,并明确指出工作单元是否为只读.对于只读工作单元,设置AutoDetectChangesEnabled = false非常安全,因为永远不会有任何变化.实际上,我们在初始发布两年后将这一更改添加到我们的系统中(因此代码中有许多预先存在的工作单元),并且更改没有破坏任何内容,并且显着提高了性能.
我们还进行了实验,AsNoTracking()发现它基本上没有提高性能.据我了解,一个查询AsNoTracking()意味着对象不会被放入身份映射中,如果在上下文中多次引用该对象(例如在不同的查询中),这将迫使EF从磁盘重新获取该对象.所以有一些潜在的缺点AsNoTracking().
实施细节:
| 归档时间: |
|
| 查看次数: |
19411 次 |
| 最近记录: |