实体框架如何适用于大量记录?

时间:2013-10-11 06:18:50

标签: c# entity-framework database-design entity-framework-6

我看到一个未回答的问题here on

我的问题是 -

  

EF真的可以为大型应用做好准备吗?

问题源于这些基本问题 -

  1. EF将所有记录拉入内存然后执行查询 操作。当表有大约1000条记录时,EF的行为如何?
  2. 为了简单编辑,我必须拉动记录编辑它     然后使用SaveChanges()
  3. 推送到数据库

5 个答案:

答案 0 :(得分:126)

我遇到了类似的情况,我们有一个大型数据库,每个表有700万到1000万条记录。我们使用Entity框架来显示数据。为了获得不错的表现,这就是我所学到的; 我的实体框架的10条黄金规则

  1. 了解只有在需要实际记录时才会调用数据库。所有操作都只是用于进行查询(SQL),因此尝试仅获取一段数据而不是请求大量记录。尽可能地修剪提取大小

  2. 是的,(在某些情况下,存储过程是更好的选择,它们并不像有些人所说的那样邪恶),您应该在必要时使用存储过程。将它们导入模型并为其进行函数导入。您也可以直接调用它们ExecuteStoreCommand(),ExecuteStoreQuery<>()。对于函数和视图也是如此,但EF有一种非常奇怪的方式来调用函数“SELECT dbo.blah(@id)”。

  3. 当必须使用深层次结构填充实体时,EF执行速度较慢。对具有深层次结构的实体要非常小心

  4. 有时,当您要求记录并且不需要修改它们时,您应该告诉EF不要观察属性更改(AutoDetectChanges)。这样记录检索要快得多

  5. 数据库的索引很好但是在EF的情况下变得非常重要。用于检索和排序的列应正确编入索引。

  6. 当你的模特很大时,VS2010 / VS2012模型设计师会变得非常疯狂。所以将您的模型打造成中型模型。有一个限制是,即使它们可能指向数据库中的同一个表,也无法共享来自不同模型的实体。

  7. 当您必须在不同位置对同一实体进行更改时,请使用同一实体,进行更改并仅保存一次。重点是AVOID检索相同的记录,进行更改和更改。多次保存。 (实际业绩增益提示)。

  8. 当您只需要一列或两列中的信息时,请尝试不要获取完整实体。你可以直接执行你的sql或者有一个迷你实体。您可能还需要在应用程序中缓存一些常用数据。

  9. 交易很慢。小心他们。

  10. SQL事件探查器或任何查询事件探查器都是您的朋友。在开发应用程序时运行它以查看EF发送到数据库的内容。当您在应用程序中使用LINQ或Lambda表达式执行连接时,EF通常会生成一个Select-Where-In-Select样式查询,该查询可能并不总是很好。如果你发现任何这种情况,请卷起你的袖子,在数据库上执行连接并获得EF检索结果。 (我忘了这个,最重要的一个!)

  11. 如果你记住这些事情,EF应该提供与普通ADO.NET几乎相同的性能,如果不相同的话。

答案 1 :(得分:19)

  

1. EF将所有记录拉入内存,然后执行查询操作。当表有大约1000条记录时,EF的行为如何?

这不是真的! EF只提取必要的记录,并将查询转换为适当的SQL语句。 EF可以在DataContext内本地缓存对象(并跟踪对实体所做的所有更改),但只要您遵循规则以仅在需要时保持上下文打开,它就不会成为问题。

  

2。对于简单的编辑,我必须拉动记录编辑它,然后使用SaveChanges()

推送到数据库

这是真的,但除非你真的看到性能问题,否则我不会打扰。因为1.不是真的,所以在保存之前,只能从DB中获取一条记录。您可以通过将SQL查询创建为字符串并将其作为纯字符串发送来绕过它。

答案 2 :(得分:6)

  1. EF将您的LINQ查询转换为SQL查询,因此它不会将所有记录都拉入内存。生成的SQL可能并不总是最有效的,但是一千条记录根本不会成为问题。
  2. 是的,这是一种方法(假设您只想编辑一条记录)。如果要更改多个记录,可以使用一个查询获取所有记录,SaveChanges()将保留所有这些更改。

答案 3 :(得分:5)

EF不是一个糟糕的ORM框架。它是一个有自己特色的不同的。比较Microsoft Entity Framework 6,而不是NetTiers,它由Microsoft Enterprise Library 6提供支持。

这是两个完全不同的野兽。接受的答案非常好,因为它经历了EF6的细微差别。需要了解的关键是每个ORM都有自己的优点和缺点。将项目需求及其数据访问模式与ORM的行为模式进行比较。

例如:NetTiers将始终为您提供比EF6更高的原始性能。然而,这主要是因为它不是点击ORM并且作为生成ORM的一部分,您将优化数据模型,在相关时添加自定义存储过程等...如果您使用相同的方法设计数据模型EF6的努力可能会接近相同的性能。

还可以考虑修改ORM吗?例如,使用NetTiers,您可以添加代码模板模板的扩展,以包含您自己的设计模式,超出基本ORM库生成的模式。

另外考虑EF6大量使用反射,而NetTiers或任何由Microsoft Enterprise Library驱动的库将大量使用泛型。这是两种完全不同的方法。为什么这样?因为EF6基于动态反射,而NetTiers基于静态反射。哪个更快,哪个更好完全取决于ORM所需的使用模式。

有时混合方法效果更好:例如考虑用于Web API OData端点的EF6,一些用NetTiers&带有自定义存储过程的Microsoft Enterprise Library,以及一些包含自定义构建的直写对象缓存的大型masterdata表,在初始加载时,使用ADO数据读取器将记录集流式传输到内存缓存中。

这些都是不同的,它们都有最适合的场景:EF6,NetTiers,NHibernate,Wilson OR Mapper,Dev Express的XPO等......

答案 4 :(得分:4)

您的问题没有简单的答案。主要是关于你想要对你的数据做什么?你一次需要这么多数据吗?

EF将您的查询转换为SQL,所以此时内存中没有对象。获取数据后,所选记录将在内存中。如果你选择了大量的大型物体,那么如果你需要操纵它们,那么它可能是一个性能杀手。

如果您不需要操作它们,您可以禁用更改跟踪,并在以后为需要操作的单个对象启用它。

所以你看,这取决于你的应用程序类型。 如果您需要高效处理大量数据,请不要使用OR-Mapper!

否则EF很好,但要考虑一次你真正需要多少个物体以及你想用它们做什么。