.net - Entity Framework 和连接池

标签 .net database entity-framework ado.net connection-pooling

我最近开始在我的 .NET 4.0 应用程序中使用 Entity Framework 4.0,并对与池相关的一些事情感到好奇。

  1. 据我所知,连接池由 ADO.NET 数据提供程序管理,在我的例子中是 MS SQL 服务器。当您实例化一个新的实体上下文 (ObjectContext),即无参数的 new MyDatabaseModelEntities() 时,这是否适用?

  2. a) 为应用程序创建全局实体上下文(即一个静态实例)或 b) 使用 为每个给定的操作/方法创建和公开实体上下文的优缺点是什么使用 block 。

  3. 我应该了解的针对特定场景的任何其他建议、最佳实践或常用方法?

最佳答案

  1. 连接池的处理方式与任何其他 ADO.NET 应用程序一样。实体连接仍然使用传统的数据库连接和传统的连接字符串。我相信如果你不想使用它,你可以关闭连接字符串中的连接池。 (阅读更多关于 SQL Server Connection Pooling (ADO.NET) 的信息)
  2. 永远不要使用全局上下文。 ObjectContext 在内部实现了多种模式,包括身份映射和工作单元。使用全局上下文的影响因应用程序类型而异。
  3. 对于网络应用程序,每个请求使用单一上下文。对于 Web 服务,每次调用使用单一上下文。在 WinForms 或 WPF 应用程序中,每个表单或每个演示者使用单个上下文。可能有一些特殊要求不允许使用这种方法,但在大多数情况下这就足够了。

如果您想知道单个对象上下文对 WPF/WinForm 应用程序有什么影响,请查看此 article .它是关于 NHibernate Session 但想法是一样的。

编辑:

当您使用 EF 时,默认情况下每个实体在每个上下文中只加载一次。第一个查询创建实体实例并将其存储在内部。任何需要具有相同键的实体的后续查询都会返回这个存储的实例。如果数据存储中的值发生变化,您仍然会收到包含初始查询值的实体。这称为身份映射模式。您可以强制对象上下文重新加载实体,但它会重新加载单个共享实例。

在您对上下文调用 SaveChanges 之前,对实体所做的任何更改都不会保留。您可以在多个实体中进行更改并一次存储它们。这称为工作单元模式。您不能有选择地说出要保存哪个修改后的附加实体。

结合这两种模式,您会看到一些有趣的效果。整个应用程序只有一个实体实例。对实体的任何更改都会影响整个应用程序,即使更改尚未持久化(提交)也是如此。在大多数情况下,这不是您想要的。假设您在 WPF 应用程序中有一个编辑表单。您正在处理该实体并决定取消复杂的编辑(更改值、添加相关实体、删除其他相关实体等)。但是该实体已经在共享上下文中进行了修改。你会怎么做?提示:我不知道 ObjectContext 上有任何 CancelChanges 或 UndoChanges。

我认为我们不必讨论服务器场景。简单地在多个 HTTP 请求或 Web 服务调用之间共享单个实体会使您的应用程序毫无用处。任何请求都可以触发 SaveChanges 并保存来自另一个请求的部分数据,因为您在所有请求之间共享一个工作单元。这还会产生另一个问题 - 上下文以及对上下文中的实体或上下文使用的数据库连接的任何操作都不是线程安全的。

即使对于只读应用程序,全局上下文也不是一个好的选择,因为每次查询应用程序时您可能都需要新数据。

关于.net - Entity Framework 和连接池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3653009/

相关文章:

c# - .Net 中当前 CultureInfo 的距离单位

支持自定义字段的 C# ID3 库

mysql - 哪个数据库管理器适用于 100Go 表?

java - 带条件(真或某些原因导致 NPE)的 Hibernate 选择列表不返回任何结果

c# - 如何使用 Entity Framework 选择单个列?

PowerShell 中的 .NET 跟踪,无需创建 .config 文件

database - 是否可以在不登录的情况下在mysql中创建用户?

.net - IQueryable<> 来自存储过程( Entity Framework )

c# - EntityFramework Core 1.1.0 缺少 Include()?

C# ThreadPool 等待结果